Obtendo o tamanho de um arquivo em Delphi 2010 ou mais tarde?
-
10-07-2019 - |
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.
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.
- http://turbopascal.org/system-functions-filepos-and-filesize
- http://docwiki.embarcadero.com/CodeExamples/XE2 / en / SystemFileSize_ (Delphi)
- http://docwiki.embarcadero.com/Libraries/XE2/en /System.FileSize
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.
- Amostra de obter comprimento e tal
- http://docwiki.embarcadero.com/Libraries/XE2 /en/System.SysUtils.FileOpen
- http://docwiki.embarcadero.com/Libraries/XE2 /en/System.SysUtils.FileSeek
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
- http://www.freepascal.org/docs -html / RTL / aulas / tfilestream.create.html
- http://www.freepascal.org/docs -html / RTL / aulas / tstream.size.html
- http://docwiki.embarcadero.com/Libraries /XE2/en/System.Classes.TFileStream.Create
- http://docwiki.embarcadero.com/Libraries / XE2 / en / System.Classes.TStream.Size
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.