代码之家  ›  专栏  ›  技术社区  ›  Wernight

获取磁盘上文件的大小

  •  81
  • Wernight  · 技术社区  · 14 年前
    var length = new System.IO.FileInfo(path).Length;
    

    我希望得到磁盘上文件的大小,用C#(最好不用 )正如Windows资源管理器所报告的那样。

    它应该给出正确的尺寸,包括:

    • 稀疏的文件
    4 回复  |  直到 10 年前
        1
  •  50
  •   Wai Ha Lee captain-yossarian from Ukraine    5 年前

    这将使用ho1建议的GetCompressedFileSize,以及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);
    
        2
  •  17
  •   Peter Mortensen icecrime    10 年前

    Windows Server 2008 或基于2008 R2或Windows7和WindowsVista的系统,因为群集大小始终为零(GetDiskFreeSpaceW和GetDiskFreeSpace返回-1,即使在 UAC 这里是修改后的代码。

    public static long GetFileSizeOnDisk(string file)
    {
        FileInfo info = new FileInfo(file);
        uint clusterSize;
        using(var searcher = new ManagementObjectSearcher("select BlockSize,NumberOfBlocks from Win32_Volume WHERE DriveLetter = '" + info.Directory.Root.FullName.TrimEnd('\\') + "'") {
            clusterSize = (uint)(((ManagementObject)(searcher.Get().First()))["BlockSize"]);
        }
        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);
    

    VB.NET版

      Private Function GetFileSizeOnDisk(file As String) As Decimal
            Dim info As New FileInfo(file)
            Dim blockSize As UInt64 = 0
            Dim clusterSize As UInteger
            Dim searcher As New ManagementObjectSearcher( _
              "select BlockSize,NumberOfBlocks from Win32_Volume WHERE DriveLetter = '" + _
              info.Directory.Root.FullName.TrimEnd("\") + _
              "'")
    
            For Each vi As ManagementObject In searcher.[Get]()
                blockSize = vi("BlockSize")
                Exit For
            Next
            searcher.Dispose()
            clusterSize = blockSize
            Dim hosize As UInteger
            Dim losize As UInteger = GetCompressedFileSizeW(file, hosize)
            Dim size As Long
            size = CLng(hosize) << 32 Or losize
            Dim bytes As Decimal = ((size + clusterSize - 1) / clusterSize) * clusterSize
    
            Return CDec(bytes) / 1024
        End Function
    
        <DllImport("kernel32.dll")> _
        Private Shared Function GetCompressedFileSizeW( _
            <[In](), MarshalAs(UnmanagedType.LPWStr)> lpFileName As String, _
            <Out(), MarshalAs(UnmanagedType.U4)> lpFileSizeHigh As UInteger) _
            As UInteger
        End Function
    
        3
  •  5
  •   CarenRose    6 年前

    磁盘上的大小应该是存储文件的群集大小的总和:
    long sizeondisk = clustersize * ((filelength + clustersize - 1) / clustersize);
    你需要深入研究一下 P/Invoke 找出聚类大小; GetDiskFreeSpace()

    看到了吗 How to get the size on disk of a file in C# .

    但请注意这一点,这将不适用于 NTFS 打开压缩的地方。

        4
  •  -1
  •   Ondrej Janacek    11 年前

    double ifileLength = (finfo.Length / 1048576); //return file size in MB ....