2012-02-03 2 views
5

나는 파일 크기 알이 rutine 있습니다델파이 XE2에서 크로스 플랫폼 방식으로 파일 크기를 얻을 방법

[DCC Warning] Funciones.pas(61): W1002 Symbol 'FindData' is specific to a platform 
이이 경고를주고, 그러나

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

이 작업을 수행하기위한 명확한 교차 플랫폼 방식이 존재하는지 궁금합니다. 내가 TFile 클래스를 확인하고 그것을 찾지 못했습니다 ...

+1

FindFirst가 파일 크기 정보를 얻는 방법 인 것처럼 보입니다. 직관적이고 항상 정확한 것은 아닙니다. –

답변

5

TSearchRec.Size 회원은 이미 Int64 (변경된 버전이 확실하지 않음)이며 Windows의 TSearchRec.FindData 필드의 전체 64 비트 값으로 채워져 있으므로 수동으로 크기를 계산할 필요가 없습니다. 예 :

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

XE에서도 마찬가지입니다. 이것이 D4-D6 타임 프레임으로 돌아 간다면 놀랄 일이 아니며 사람들은 ifdef 구조를 유지했습니다. 왜냐하면 아주 오래된 버전에서도 작동했기 때문입니다. 그러나 거의 아무도 D7 이전 버전을 아직 지원하지 않기 때문에 짐승을 죽일 때라고 생각합니다. –

+0

Delphi 2006에서 Int64로 전환했습니다. –

4

FindData 구조의 구성원이 TSearchRec 구조이기 때문에 경고 메시지가 표시되지만 걱정할 필요가 없습니다. 코드에서 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. 좋은 캐치! –

+0

@TLama 경고를 제거하지 않습니다. –

+0

@ 프랑수아, 문제는 크로스 플랫폼 솔루션 (OP가 이미 가지고있는)이 아니라 경고를 억제하는 방법입니다;) 그러나 나는 당신의 방식 (+ 1ed)을 좋아합니다 – TLama

4

이미 Windows에서 실행 확인 때문에, 컴파일러에 의해보고 된 유일한 "진짜"경고를 유지하기 위해 로컬 경고를 제거하는 것이 안전합니다 :

델파이 XE2에서
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);