1. ホーム
  2. c#

[解決済み] ディスク上のファイルサイズを取得する

2023-04-28 19:21:19

質問

var length = new System.IO.FileInfo(path).Length;

これは、ディスク上のサイズではなく、ファイルの論理的なサイズを与えます。

私はC#でディスク上のファイルサイズを取得したいのですが、(できれば 相互運用 を使用せずに)Windows エクスプローラーによって報告されるような、ディスク上のファイルのサイズを C# で取得したいです。

を含む正しいサイズを示すはずです。

  • 圧縮されたファイル
  • スパースファイル
  • 断片化されたファイル

どのように解決するのですか?

これは、ho1 が提案した GetCompressedFileSize と、PaulStack が提案した GetDiskFreeSpace を使用します。 が提案したように、これは P/Invoke を使用します。私は圧縮ファイルに対してのみこれをテストしました。

public static long GetFileSizeOnDisk(string file)
{
    FileInfo info = new FileInfo(file);
    uint dummy, sectorsPerCluster, bytesPerSector;
    int result = GetDiskFreeSpaceW(info.Directory.Root.FullName, out sectorsPerCluster, out bytesPerSector, out dummy, out dummy);
    if (result == 0) throw new Win32Exception();
    uint clusterSize = sectorsPerCluster * bytesPerSector;
    uint hosize;
    uint losize = GetCompressedFileSizeW(file, out hosize);
    long size;
    size = (long)hosize << 32 | losize;
    return ((size + clusterSize - 1) / clusterSize) * clusterSize;
}

[DllImport("kernel32.dll")]
static extern uint GetCompressedFileSizeW([In, MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
   [Out, MarshalAs(UnmanagedType.U4)] out uint lpFileSizeHigh);

[DllImport("kernel32.dll", SetLastError = true, PreserveSig = true)]
static extern int GetDiskFreeSpaceW([In, MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName,
   out uint lpSectorsPerCluster, out uint lpBytesPerSector, out uint lpNumberOfFreeClusters,
   out uint lpTotalNumberOfClusters);