web-dev-qa-db-ja.com

Delphi 2010以降でファイルのサイズを取得していますか?

Delphi 2010には、IOUtils.pasに新しいファイルアクセス関数の素晴らしいセットがあります(特に、日付に関連する関数のUTCバージョンが好きです)。これまでに見逃しているのは

TFile.GetSize (const Path : String)

Delphi 2010でファイルのサイズを取得する方法は何ですか?戻ってFindFirstを使用してTSearchRec.FindDataにアクセスする必要がありますか?

ありがとう。

28
jpfollenius

"Delphi 2010"の方法があるかどうかはわかりませんが、 FindFirstとそのすべてのジャズを含まないWindowsの方法 があります。

私はそのルーチンのこのDelphi変換を一緒に投げました(そして、その過程でそれが4GBを超えるサイズのファイルを処理するように変更しました。

  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;

GetFileSize()を実際に使用することもできますが、これにはファイル名だけでなく、GetCompressedFileSize()の提案、これには2つの変数を呼び出す必要があります。 GetFileSize()GetCompressedFileSize()の両方が戻り値をオーバーロードするため、成功のテストと有効な結果の確認は、少し厄介です。

GetFileSizeEx()は、4 GBを超えるファイルサイズを処理し、有効な結果を検出するという要領を回避しますが、また、名前ではなくファイルHANDLEが必要であり、(少なくともDelphi 2009では2010を確認していません)VCLで宣言されていない場合は、独自のインポート宣言を提供する必要があります。

48
Deltics

Indyユニットの使用:

uses IdGlobalProtocols;

function FileSizeByName(const AFilename: TIdFileName): Int64;
7
tz.

DSiWin32 からDSiFileSizeを使用することもできます。 「すべての」Delphisで動作します。内部的には、CreateFileと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 }
4
gabr

いくつかのPure Delphi方法について言及します。 DelticsWindowsプラットフォームに対して最も速度効率の良い答えを出したと思いますが、場合によってはRTLに依存して、 Delphi for MacOSまたはFreePascal/Virtual Pascal/whateverで動作する移植可能なコード。


Turbo Pascalの時代から残っているFileSize関数があります。

上記のサンプルには、「読み取り専用」モード設定がありません。 CD-ROMメディアや、ACLがr/oに設定されているフォルダーなどのr/oファイルを開く必要があります。 ReSetを呼び出す前に、FileModeグローバル変数にゼロが割り当てられている必要があります。

2GBを超えるサイズのファイル(おそらくネガティブからカーディナルキャスト-最大4GBまで)では機能しませんが、「そのまま」のファイルです。


MS-DOS用のASMプログラミングを行ったことがあれば、もう1つのアプローチがあります。 Seekファイルポインターを最初のバイトに、次に最後のバイトに移動し、違いを確認します。
どのDelphiバージョンがそれらを導入したか正確には言えませんが、それはすでにD5やD7などの古いバージョンにあったと思いますが、それは常識であり、確認することはできません。
その場合、追加のTHandle変数とtry-finallyブロックを使用して、サイズが取得された後に常にハンドルを閉じます。

最初のアプローチを除いて、これはint64対応です。 FreePascalとも互換性がありますが、いくつかの制限があります


TFileStreamタイプのオブジェクトを作成して使用することもできます-これはプライマリであり、正式に祝福されましたDelphi 1.0以降のファイル操作の手段

補足として、この道はもちろん前述のIOUtilsユニットと統合されています。

3
Arioch 'The
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;
1
Richard Winston

これは、仕事をするFileSizeを使用した短いソリューションです。

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;

私が知っていることから、FileSizeはXE2からのみ利用可能です。

1
pavel.lazar