【问题标题】:Get free disk space获取可用磁盘空间
【发布时间】:2010-11-26 11:52:14
【问题描述】:

鉴于以下每个输入,我想在该位置获得可用空间。类似的东西

long GetFreeSpace(string path)

输入:

c:

c:\

c:\temp

\\server

\\server\C\storage

【问题讨论】:

  • 不是重复的,stackoverflow.com/questions/412632 只询问磁盘,我还询问 UNC 路径,而 412632 中的解决方案对它们不起作用。

标签: c# diskspace


【解决方案1】:

这对我有用...

using System.IO;

private long GetTotalFreeSpace(string driveName)
{
    foreach (DriveInfo drive in DriveInfo.GetDrives())
    {
        if (drive.IsReady && drive.Name == driveName)
        {
            return drive.TotalFreeSpace;
        }
    }
    return -1;
}

祝你好运!

【讨论】:

  • drive.TotalFreeSpace 不适合我,但drive.AvailableFreeSpace 可以
  • 我知道这个答案很古老,但您通常需要使用AvailableFreeSpace,正如@knocte 所说。 AvailableFreeSpace 列出了用户实际可用的数量(由于报价)。 TotalFreeSpace 列出磁盘上可用的内容,无论用户可以使用什么。
  • 我赞成@RoyT 的评论,因为他花时间解释了为什么推荐其中一个而不是另一个。
  • 这对我来说效果很好(以'availableSpace' cmets为模),但是create a new DriveInfo from the driveName似乎更简单、更健壮的方法,而不是遍历所有内容并检查匹配的名称.
【解决方案2】:

使用来自 RichardOD 链接的GetDiskFreeSpaceEx 的工作代码 sn-p。

// Pinvoke for API function
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
out ulong lpFreeBytesAvailable,
out ulong lpTotalNumberOfBytes,
out ulong lpTotalNumberOfFreeBytes);

public static bool DriveFreeBytes(string folderName, out ulong freespace)
{
    freespace = 0;
    if (string.IsNullOrEmpty(folderName))
    {
        throw new ArgumentNullException("folderName");
    }

    if (!folderName.EndsWith("\\"))
    {
        folderName += '\\';
    }

    ulong free = 0, dummy1 = 0, dummy2 = 0;

    if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2))
    {
        freespace = free;
        return true;
    }
    else
    {
        return false;
    }
}

【讨论】:

  • 我宁愿让它返回 void,例如 ... if (!GetDiskFreeSpaceEx(folderName, out free, out total, out dummy)) throw new Win32Exception(Marshal.GetLastWin32Error());。反正在这里找代码挺方便的。
  • 只是检查,但我认为“CameraStorageFileHelper”是从原始代码复制粘贴而来的工件?
  • 不需要以"\\"结尾。它可以是任何现有的目录路径,甚至只是C:。这是我的代码版本:stackoverflow.com/a/58005966/964478
【解决方案3】:

DriveInfo 将帮助您解决其中的一些问题(但它不适用于 UNC 路径),但实际上我认为您需要使用 GetDiskFreeSpaceEx。您可能可以使用 WMI 实现一些功能。 GetDiskFreeSpaceEx 看起来是您的最佳选择。

您可能需要清理路径才能使其正常工作。

【讨论】:

    【解决方案4】:
    using System;
    using System.IO;
    
    class Test
    {
        public static void Main()
        {
            DriveInfo[] allDrives = DriveInfo.GetDrives();
    
            foreach (DriveInfo d in allDrives)
            {
                Console.WriteLine("Drive {0}", d.Name);
                Console.WriteLine("  Drive type: {0}", d.DriveType);
                if (d.IsReady == true)
                {
                    Console.WriteLine("  Volume label: {0}", d.VolumeLabel);
                    Console.WriteLine("  File system: {0}", d.DriveFormat);
                    Console.WriteLine(
                        "  Available space to current user:{0, 15} bytes", 
                        d.AvailableFreeSpace);
    
                    Console.WriteLine(
                        "  Total available space:          {0, 15} bytes",
                        d.TotalFreeSpace);
    
                    Console.WriteLine(
                        "  Total size of drive:            {0, 15} bytes ",
                        d.TotalSize);
                }
            }
        }
    }
    /* 
    This code produces output similar to the following:
    
    Drive A:\
      Drive type: Removable
    Drive C:\
      Drive type: Fixed
      Volume label: 
      File system: FAT32
      Available space to current user:     4770430976 bytes
      Total available space:               4770430976 bytes
      Total size of drive:                10731683840 bytes 
    Drive D:\
      Drive type: Fixed
      Volume label: 
      File system: NTFS
      Available space to current user:    15114977280 bytes
      Total available space:              15114977280 bytes
      Total size of drive:                25958948864 bytes 
    Drive E:\
      Drive type: CDRom
    
    The actual output of this code will vary based on machine and the permissions
    granted to the user executing it.
    */
    

    【讨论】:

    • 虽然此代码实际上适用于系统上的所有驱动器,但它并没有解决 OP 对挂载点、连接点和共享的要求...
    【解决方案5】:

    这是@sasha_gud 答案的重构和简化版本:

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
            out ulong lpFreeBytesAvailable,
            out ulong lpTotalNumberOfBytes,
            out ulong lpTotalNumberOfFreeBytes);
    
        public static ulong GetDiskFreeSpace(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
    
            ulong dummy = 0;
    
            if (!GetDiskFreeSpaceEx(path, out ulong freeSpace, out dummy, out dummy))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
    
            return freeSpace;
        }
    

    【讨论】:

    • 你的方法更好,因为你提取了 LastWin32Error
    【解决方案6】:

    检查一下(这对我来说是一个可行的解决方案)

    public long AvailableFreeSpace()
    {
        long longAvailableFreeSpace = 0;
        try{
            DriveInfo[] arrayOfDrives = DriveInfo.GetDrives();
            foreach (var d in arrayOfDrives)
            {
                Console.WriteLine("Drive {0}", d.Name);
                Console.WriteLine("  Drive type: {0}", d.DriveType);
                if (d.IsReady == true && d.Name == "/data")
                {
                    Console.WriteLine("Volume label: {0}", d.VolumeLabel);
                    Console.WriteLine("File system: {0}", d.DriveFormat);
                    Console.WriteLine("AvailableFreeSpace for current user:{0, 15} bytes",d.AvailableFreeSpace);
                    Console.WriteLine("TotalFreeSpace {0, 15} bytes",d.TotalFreeSpace);
                    Console.WriteLine("Total size of drive: {0, 15} bytes \n",d.TotalSize);
                    }
                    longAvailableFreeSpaceInMB = d.TotalFreeSpace;
            }
        }
        catch(Exception ex){
            ServiceLocator.GetInsightsProvider()?.LogError(ex);
        }
        return longAvailableFreeSpace;
    }
    

    【讨论】:

      【解决方案7】:

      未经测试:

      using System;
      using System.Management;
      
      ManagementObject disk = new
      ManagementObject("win32_logicaldisk.deviceid="c:"");
      disk.Get();
      Console.WriteLine("Logical Disk Size = " + disk["Size"] + " bytes");
      Console.WriteLine("Logical Disk FreeSpace = " + disk["FreeSpace"] + "
      bytes"); 
      

      顺便说一句,c:\temp 上可用磁盘空间的结果是什么?您将获得没有 c:\

      的空间

      【讨论】:

      • 正如 Kenny 所说,任何给定目录的可用空间不一定与根目录驱动器的可用空间相同。肯定不在我的机器上。
      【解决方案8】:

      我正在寻找以 GB 为单位的大小,所以我只是通过以下更改改进了上面超人的代码:

      public double GetTotalHDDSize(string driveName)
      {
          foreach (DriveInfo drive in DriveInfo.GetDrives())
          {
              if (drive.IsReady && drive.Name == driveName)
              {
                  return drive.TotalSize / (1024 * 1024 * 1024);
              }
          }
          return -1;
      }
      

      【讨论】:

      • 您正在返回驱动器的总容量。
      • 我认为任何人都可以计算具有字节的 GB,但您证明这是错误的假设。 Tis 代码错误,因为除法使用 long 但函数返回 double
      【解决方案9】:

      看到这个article

      1. 通过搜索“:”的索引来识别 UNC par 或本地驱动器路径

      2. 如果它是 UNC 路径,您可以映射 UNC 路径

      3. 执行驱动器名称的代码是映射驱动器名称

        using System.IO;
        
        private long GetTotalFreeSpace(string driveName)
        {
        foreach (DriveInfo drive in DriveInfo.GetDrives())
        {
            if (drive.IsReady && drive.Name == driveName)
            {
                return drive.TotalFreeSpace;
            }
        }
        return -1;
        }
        
      4. 完成要求后取消映射。

      【讨论】:

      • 虽然此代码实际上适用于系统上的所有驱动器,但它并没有解决 OP 对安装点和连接点的要求...
      【解决方案10】:

      正如this answer 和@RichardOD 建议的那样,你应该这样做:

      [DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
      [return: MarshalAs(UnmanagedType.Bool)]
      static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
         out ulong lpFreeBytesAvailable,
         out ulong lpTotalNumberOfBytes,
         out ulong lpTotalNumberOfFreeBytes);
      
      ulong FreeBytesAvailable;
      ulong TotalNumberOfBytes;
      ulong TotalNumberOfFreeBytes;
      
      bool success = GetDiskFreeSpaceEx(@"\\mycomputer\myfolder",
                                        out FreeBytesAvailable,
                                        out TotalNumberOfBytes,
                                        out TotalNumberOfFreeBytes);
      if(!success)
          throw new System.ComponentModel.Win32Exception();
      
      Console.WriteLine("Free Bytes Available:      {0,15:D}", FreeBytesAvailable);
      Console.WriteLine("Total Number Of Bytes:     {0,15:D}", TotalNumberOfBytes);
      Console.WriteLine("Total Number Of FreeBytes: {0,15:D}", TotalNumberOfFreeBytes);
      

      【讨论】:

        【解决方案11】:

        我想为我的项目使用类似的方法,但在我的情况下,输入路径来自本地磁盘卷或集群存储卷 (CSV)。所以 DriveInfo 类对我不起作用。 CSV 在另一个驱动器下有一个挂载点,通常是 C:\ClusterStorage\Volume*。请注意,C: 将是与 C:\ClusterStorage\Volume1 不同的卷

        这是我最终想到的:

            public static ulong GetFreeSpaceOfPathInBytes(string path)
            {
                if ((new Uri(path)).IsUnc)
                {
                    throw new NotImplementedException("Cannot find free space for UNC path " + path);
                }
        
                ulong freeSpace = 0;
                int prevVolumeNameLength = 0;
        
                foreach (ManagementObject volume in
                        new ManagementObjectSearcher("Select * from Win32_Volume").Get())
                {
                    if (UInt32.Parse(volume["DriveType"].ToString()) > 1 &&                             // Is Volume monuted on host
                        volume["Name"] != null &&                                                       // Volume has a root directory
                        path.StartsWith(volume["Name"].ToString(), StringComparison.OrdinalIgnoreCase)  // Required Path is under Volume's root directory 
                        )
                    {
                        // If multiple volumes have their root directory matching the required path,
                        // one with most nested (longest) Volume Name is given preference.
                        // Case: CSV volumes monuted under other drive volumes.
        
                        int currVolumeNameLength = volume["Name"].ToString().Length;
        
                        if ((prevVolumeNameLength == 0 || currVolumeNameLength > prevVolumeNameLength) &&
                            volume["FreeSpace"] != null
                            )
                        {
                            freeSpace = ulong.Parse(volume["FreeSpace"].ToString());
                            prevVolumeNameLength = volume["Name"].ToString().Length;
                        }
                    }
                }
        
                if (prevVolumeNameLength > 0)
                {
                    return freeSpace;
                }
        
                throw new Exception("Could not find Volume Information for path " + path);
            }
        

        【讨论】:

          【解决方案12】:

          你可以试试这个:

          var driveName = "C:\\";
          var freeSpace = DriveInfo.GetDrives().Where(x => x.Name == driveName && x.IsReady).FirstOrDefault().TotalFreeSpace;
          

          祝你好运

          【讨论】:

          • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
          • var driveName = "C:\\";
          【解决方案13】:

          我遇到了同样的问题,我看到 waruna manjula 给出了最好的答案。 然而,在控制台上写下来并不是你想要的。 要从 al 信息中获取字符串,请使用以下命令

          第一步:在开始时声明值

              //drive 1
              public static string drivename = "";
              public static string drivetype = "";
              public static string drivevolumelabel = "";
              public static string drivefilesystem = "";
              public static string driveuseravailablespace = "";
              public static string driveavailablespace = "";
              public static string drivetotalspace = "";
          
              //drive 2
              public static string drivename2 = "";
              public static string drivetype2 = "";
              public static string drivevolumelabel2 = "";
              public static string drivefilesystem2 = "";
              public static string driveuseravailablespace2 = "";
              public static string driveavailablespace2 = "";
              public static string drivetotalspace2 = "";
          
              //drive 3
              public static string drivename3 = "";
              public static string drivetype3 = "";
              public static string drivevolumelabel3 = "";
              public static string drivefilesystem3 = "";
              public static string driveuseravailablespace3 = "";
              public static string driveavailablespace3 = "";
              public static string drivetotalspace3 = "";
          

          第 2 步:实际代码

                          DriveInfo[] allDrives = DriveInfo.GetDrives();
                          int drive = 1;
                          foreach (DriveInfo d in allDrives)
                          {
                              if (drive == 1)
                              {
                                  drivename = String.Format("Drive {0}", d.Name);
                                  drivetype = String.Format("Drive type: {0}", d.DriveType);
                                  if (d.IsReady == true)
                                  {
                                      drivevolumelabel = String.Format("Volume label: {0}", d.VolumeLabel);
                                      drivefilesystem = String.Format("File system: {0}", d.DriveFormat);
                                      driveuseravailablespace = String.Format("Available space to current user:{0, 15} bytes", d.AvailableFreeSpace);
                                      driveavailablespace = String.Format("Total available space:{0, 15} bytes", d.TotalFreeSpace);
                                      drivetotalspace = String.Format("Total size of drive:{0, 15} bytes ", d.TotalSize);
                                  }
                                  drive = 2;
                              }
                              else if (drive == 2)
                              {
                                  drivename2 = String.Format("Drive {0}", d.Name);
                                  drivetype2 = String.Format("Drive type: {0}", d.DriveType);
                                  if (d.IsReady == true)
                                  {
                                      drivevolumelabel2 = String.Format("Volume label: {0}", d.VolumeLabel);
                                      drivefilesystem2 = String.Format("File system: {0}", d.DriveFormat);
                                      driveuseravailablespace2 = String.Format("Available space to current user:{0, 15} bytes", d.AvailableFreeSpace);
                                      driveavailablespace2 = String.Format("Total available space:{0, 15} bytes", d.TotalFreeSpace);
                                      drivetotalspace2 = String.Format("Total size of drive:{0, 15} bytes ", d.TotalSize);
                                  }
                                  drive = 3;
                              }
                              else if (drive == 3)
                              {
                                  drivename3 = String.Format("Drive {0}", d.Name);
                                  drivetype3 = String.Format("Drive type: {0}", d.DriveType);
                                  if (d.IsReady == true)
                                  {
                                      drivevolumelabel3 = String.Format("Volume label: {0}", d.VolumeLabel);
                                      drivefilesystem3 = String.Format("File system: {0}", d.DriveFormat);
                                      driveuseravailablespace3 = String.Format("Available space to current user:{0, 15} bytes", d.AvailableFreeSpace);
                                      driveavailablespace3 = String.Format("Total available space:{0, 15} bytes", d.TotalFreeSpace);
                                      drivetotalspace3 = String.Format("Total size of drive:{0, 15} bytes ", d.TotalSize);
                                  }
                                  drive = 4;
                              }
                              if (drive == 4)
                              {
                                  drive = 1;
                              }
                          }
          
                          //part 2: possible debug - displays in output
          
                          //drive 1
                          Console.WriteLine(drivename);
                          Console.WriteLine(drivetype);
                          Console.WriteLine(drivevolumelabel);
                          Console.WriteLine(drivefilesystem);
                          Console.WriteLine(driveuseravailablespace);
                          Console.WriteLine(driveavailablespace);
                          Console.WriteLine(drivetotalspace);
          
                          //drive 2
                          Console.WriteLine(drivename2);
                          Console.WriteLine(drivetype2);
                          Console.WriteLine(drivevolumelabel2);
                          Console.WriteLine(drivefilesystem2);
                          Console.WriteLine(driveuseravailablespace2);
                          Console.WriteLine(driveavailablespace2);
                          Console.WriteLine(drivetotalspace2);
          
                          //drive 3
                          Console.WriteLine(drivename3);
                          Console.WriteLine(drivetype3);
                          Console.WriteLine(drivevolumelabel3);
                          Console.WriteLine(drivefilesystem3);
                          Console.WriteLine(driveuseravailablespace3);
                          Console.WriteLine(driveavailablespace3);
                          Console.WriteLine(drivetotalspace3);
          

          我想指出你可以让所有的控制台写行注释代码,但我认为你测试它会很好。 如果您将所有这些一个接一个地显示,您将获得与 waruna majuna 相同的列表

          驱动器 C:\ 驱动类型:固定 体积标识: 文件系统:NTFS 当前用户可用空间:134880153600 字节 总可用空间:134880153600 字节 驱动器总大小:499554185216 字节

          驱动器 D:\ 驱动器类型:光驱

          驱动器 H:\ 驱动类型:固定 卷标:硬盘 文件系统:NTFS 当前用户的可用空间:2000010817536 字节 总可用空间:2000010817536 字节 驱动器总大小:2000263573504 字节

          但是您现在可以访问字符串中的所有松散信息

          【讨论】:

          • 不为 3 个类似对象创建类并使用 else if。我哭了一点。
          • 对不起锅炉电镀代码,不使用集合而不使用开关?
          猜你喜欢
          • 2019-12-12
          • 2012-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多