Pergunta

Delphi 2010 tem um bom conjunto de novas funções de acesso a arquivos em IOUtils.pas (I especialmente como as versões UTC das funções relacionadas à data). O que eu sinto falta até agora é algo como

TFile.GetSize (const Path : String)

O que é o Delphi 2010-maneira de obter o tamanho de um arquivo? Eu tenho que voltar e usar FindFirst para acesso TSearchRec.FindData?

Graças.

Foi útil?

Solução

Eu não tenho certeza se há uma maneira "Delphi 2010", mas há uma Windows maneira que não envolva FindFirst e todos jazz que .

Eu joguei junto esta conversão Delphi de que a rotina (e no processo modificado para identificador> arquivos de tamanho de 4 GB, se você precisar que).

  uses
    WinApi.Windows;

  function FileSize(const aFilename: String): Int64;
  var
    info: TWin32FileAttributeData;
  begin
    result := -1;

    if NOT GetFileAttributesEx(PWideChar(aFileName), GetFileExInfoStandard, @info) then
      EXIT;

    result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
  end;

Você poderia realmente usar apenas GetFileSize () , mas isso requer um identificador de arquivo, não apenas um nome de arquivo, e semelhante ao GetCompressedFileSize () sugestão, isso exige dois variáveis ??para chamar. Ambos GetFileSize () e GetCompressedFileSize () sobrecarga de seu valor de retorno, de modo a testar para o sucesso e garantindo um resultado válido é apenas um pouco mais complicado.

GetFileSize Ex () evita o âmago da questão de lidar com> tamanhos de arquivo de 4GB e detectar resultados válidos, mas também requer um identificador de arquivo, em vez de um nome, e ( a partir de Delphi 2009, pelo menos, eu não tenho verificado 2010) não é declarada por você no lugar VCL, você teria que fornecer sua própria declaração de importação.

Outras dicas

Usando uma unidade de Indy:

uses IdGlobalProtocols;

function FileSizeByName(const AFilename: TIdFileName): Int64;

Você também pode usar DSiFileSize de DSiWin32 . Trabalha em "todos" Delphis. Internamente ele chama CreateFile e GetFileSize.

function DSiFileSize(const fileName: string): int64;
  var
    fHandle: DWORD;
  begin
    fHandle := CreateFile(PChar(fileName), 0, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    if fHandle = INVALID_HANDLE_VALUE then
      Result := -1
    else try
      Int64Rec(Result).Lo := GetFileSize(fHandle, @Int64Rec(Result).Hi);
    finally CloseHandle(fHandle); end;
  end; { DSiFileSize }

Eu gostaria de mencionar alguns Pure Delphi maneiras. Embora eu acho que Deltics fez uma resposta mais velocidade eficaz para plataforma Windows , mas às vezes você quer apenas contar com RTL e também tornar o código portátil que iria trabalhar em Delphi para MacOS ou FreePascal / Virtual Pascal / whatever .


Não é função FileSize deixou de dias Turbo Pascal.

O exemplo acima carece de "read-only" Configuração do modo. Você exigiria que a r aberta / o arquivo, como um em mídia CD-ROM ou na pasta com ACLs definidas para r / o. Antes de chamar ReSet não deve ser zero atribuído a FileMode var global.

Não iria trabalhar em arquivos acima de tamanho de 2GB (talvez com negativa ao Cardeal elenco - até 4GB), mas é "fora da caixa" one

.

Há mais uma abordagem, que você pode estar familiarizado se você já fez a programação ASM para MS-DOS. Você Seek ponteiro de arquivo a 1 byte, em seguida, até o último byte, e verificar a diferença.
Eu não posso dizer exatamente qual versão Delphi introduziu aqueles, mas eu acho que já estava em alguma versão antiga como D5 ou D7, no entanto, que é apenas o senso comum e não pode verificá-lo.
Isso levaria uma variável THandle e bloco try-finally extra para sempre fechar o identificador após o tamanho foi obtido.

Além de 1ª abordagem é int64-capable. Ele também é compatível com FreePascal, embora com algumas limitações


Você também pode criar e usar digitado-TFileStream objeto - que era a principal , oficialmente abençoado avenida para operações de arquivo desde Delphi 1.0

Como uma nota lado, esta via é de curso integrado com a unidade de IOUtils acima mencionado.

uses
  System.Classes, System.IOUtils;

function GetFileSize(const FileName : string) : Int64;
var
  Reader: TFileStream;
begin
  Reader := TFile.OpenRead(FileName);
  try
    result := Reader.Size;
  finally
    Reader.Free;
  end;
end;

Esta é uma solução de curto usando FileSize que faz o trabalho:

function GetFileSize(p_sFilePath : string) : Int64;
var
  oFile : file of Byte;
begin
  Result := -1;
  AssignFile(oFile, p_sFilePath);
  try
    Reset(oFile);
    Result := FileSize(oFile);
  finally
    CloseFile(oFile);
  end;
end;

Pelo que eu sei, FileSize está disponível apenas a partir de XE2.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top