2012-02-03 16 views
5

mam ten rutine znać Wielkość pliku:Jak uzyskać rozmiar pliku w cross-platformowej sposób o Delphi XE2

(na podstawie 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; 

to jednak daje to ostrzeżenie:

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

Zastanawiam się, czy istnieje czysty, międzyplatformowy sposób, aby to zrobić. Sprawdzam klasę TFile i jej nie znalazłem ...

+1

To przygnębia mnie, że FindFirst wydaje się być sposobem na uzyskanie informacji o rozmiarze pliku. Jest to sprzeczne z intuicją i nie zawsze dokładne. –

Odpowiedz

5

w Delphi XE2 The TSearchRec.Size Użytkownik już jest Int64 (nie jest pewien, która wersja się zmieniła) i jest wypełniony pełną 64-bitową wartością z pól TSearchRec.FindData w systemie Windows, więc nie ma potrzeby ręcznego obliczania rozmiaru, np .:

{$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

Tak samo jest w XE. Nie zdziwiłbym się, gdyby to wszystko powróciło do ram czasowych D4-D6, a ludzie zachowywali konstrukcję ifdef, ponieważ działało również na bardzo starych wersjach. Ale ponieważ prawie nikt nie obsługuje jeszcze wersji przed D7, myślę, że nadszedł czas, aby zabić bestię. –

+0

Przełączono na Int64 w Delphi 2006. –

4

Ostrzeżenie, które otrzymujesz, ponieważ element FindData struktury TSearchRec jest specyficzny dla platformy Windows, ale nie musisz się tym martwić, ponieważ w swoim kodzie jesteś brak dostępu do tego członka, gdy jesteś na platformie innej niż 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. Dobry chwyt! –

+0

@TLama, to nie usuwa ostrzeżenia. –

+0

Ale @ François, pytanie brzmi, czy istnieje rozwiązanie wieloplatformowe (co OP już posiada), a nie jak tłumić ostrzeżenie;) Ale podoba mi się twoja droga (+ 1ed) – TLama

4

Bo już sprawdzić używasz Windows, to można bezpiecznie usunąć lokalnie Ostrzeżenie zachować tylko "prawdziwe" ostrzeżenia zgłoszone przez kompilator:

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} 
Powiązane problemy