一尘不染

获取磁盘上文件的大小

c#

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

这给出了文件的逻辑大小,而不是磁盘上的大小。

我希望获得Windows资源管理器报告的C#磁盘上文件的大小(最好没有 interop )。

它应该给出正确的大小,包括:

  • 压缩文件
  • 稀疏文件
  • 碎片文件

阅读 280

收藏
2020-05-19

共1个答案

一尘不染

它使用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);
2020-05-19