2012-02-03 7 views
5

tengo esta rutina para saber el tamaño del archivo:Cómo conseguir tamaño del archivo en forma de plataformas cruzadas en XE2 delphi

(Basado en http://delphi.about.com/od/delphitips2008/qt/filesize.htm)

function FileSize(fileName : String) : Int64; 
var 
    sr : TSearchRec; 
begin 
    if FindFirst(fileName, faAnyFile, sr) = 0 then 
    {$IFDEF MSWINDOWS} 
    result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow) 
    {$ELSE} 
    result := sr.Size 
    {$ENDIF} 
    else 
    result := -1; 

    FindClose(sr) ; 
end; 

Sin embargo, esto dará esta advertencia:

[DCC Warning] Funciones.pas(61): W1002 Symbol 'FindData' is specific to a platform 

Me pregunto si existe una forma clara de plataforma cruzada para hacer esto. Compruebo la clase TFile y no la encontré ...

+1

Me deprime que FindFirst parezca ser la forma de obtener información sobre el tamaño del archivo. Es contador intuitivo y ni siquiera siempre exacto. –

Respuesta

5

En Delphi XE2, la TSearchRec.Size miembro ya es un Int64 (no estoy seguro de qué versión cambió) y se completa con el valor completo de 64 bits de los campos TSearchRec.FindData en Windows, por lo que no es necesario calcular el tamaño manualmente, por ejemplo:

{$IFDEF VER230} 
    {$DEFINE USE_TSEARCHREC_SIZE} 
{$ELSE} 
    {$IFNDEF MSWINDOWS} 
    {$DEFINE USE_TSEARCHREC_SIZE} 
    {$ENDIF} 
{$ENDIF} 

function FileSize(fileName : String) : Int64; 
var 
    sr : TSearchRec; 
begin 
    if FindFirst(fileName, faAnyFile, sr) = 0 then 
    begin 
    {$IFDEF USE_TSEARCHREC_SIZE} 
    Result := sr.Size; 
    {$ELSE} 
    Result := (Int64(sr.FindData.nFileSizeHigh) shl 32) + sr.FindData.nFileSizeLow; 
    {$ENDIF} 
    FindClose(sr); 
    end 
    else 
    Result := -1; 
end; 
+0

Lo mismo ocurre en XE. No me sorprendería si esto llega hasta el período de tiempo D4-D6, y la gente mantuvo el constructo ifdef porque también funcionaba en versiones muy antiguas. Pero dado que casi nadie sigue siendo compatible con versiones anteriores a D7, creo que es hora de matar a la bestia. –

+0

Cambió a un Int64 en Delphi 2006. –

4

La advertencia que está recibiendo porque el miembro FindData de la estructura TSearchRec es específico de la plataforma Windows, pero no necesita preocuparse porque en su código está no acceder a ese miembro cuando se encuentra en una plataforma diferente a Windows.

// condition if you are on the Windows platform 
{$IFDEF MSWINDOWS} 
    // here you can access the FindData member because you are 
    // on Windows 
    Result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + 
    Int64(sr.FindData.nFileSizeLow); 
{$ELSE} 
    // here you can't use FindData member and you would even 
    // get the compiler error because the FindData member is 
    // Windows specific and you are now on different platform 
{$ENDIF} 
+1

+1. ¡Buena atrapada! –

+0

@TLama, esto no elimina la advertencia. –

+0

Pero @ François, la pregunta es si hay una solución multiplataforma (lo que OP ya tiene), no cómo suprimir la advertencia;) Pero me gusta tu camino (+ 1ed) – TLama

4

Debido a que ya comprobar que está ejecutando en Windows, es seguro retirar localmente la advertencia de mantener sólo las advertencias "reales" reportados por el compilador:

if FindFirst(fileName, faAnyFile, sr) = 0 then 
    {$IFDEF MSWINDOWS} 
    {$WARN SYMBOL_PLATFORM OFF} 
    result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow) 
    {$WARN SYMBOL_PLATFORM ON} 
    {$ELSE} 
0
TDirectory.GetLastWriteTime(path); 
Cuestiones relacionadas