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

在.NET中查找总磁盘空间和可用磁盘空间

  •  15
  • CesarGon  · 技术社区  · 14 年前

    我正试图找到一种方法来确定.NET应用程序中任意文件夹中的总磁盘空间和可用磁盘空间。通过文件夹中的“总磁盘空间”和“可用磁盘空间”,我指的是如果对文件夹执行了“dir”命令,则此文件夹将报告的总可用磁盘空间,即包含该文件夹的逻辑驱动器的总可用磁盘空间,考虑到发出请求所使用的用户帐户。

    我用的是C。该方法应同时适用于作为UNC路径提供的本地和远程文件夹(而不是通过映射的驱动器号访问)。例如,它应该适用于:

    • C:温度
    • \\四分\资源\模板2

    我从directoryInfo对象开始,但这似乎没有关联的磁盘空间信息。DriveInfo类可以,但它不能与远程文件夹一起使用。

    编辑。 在和你们交换了一些信息之后,我考虑将远程文件夹映射为本地驱动器,使用driveinfo获取数据,然后再次取消映射。这种方法的问题在于,我的应用程序每天需要收集超过120个文件夹的数据几次。我不确定这是否可行。

    有什么想法吗?谢谢。

    9 回复  |  直到 14 年前
        1
  •  11
  •   George Stocker NotMe    14 年前

    怎么样 this link from MSDN 它使用 System.IO.DriveInfo 班级?

        2
  •  11
  •   user283601    14 年前

    你可以使用 GetDiskFreeSpaceEx from kernel32.dll 它与UNC路径和驱动器一起工作。您需要做的只是包含一个dllimport(请参见链接以获取示例)。

        3
  •  3
  •   Matthew Lock fge    11 年前

    这个 可以 不是你想要的,但我正在努力帮助你,它的好处是可以稍微安全地删除你的硬盘空间。

    public static string DriveSizeAvailable(string path)
    {
        long count = 0;
        byte toWrite = 1;
        try
        {
            using (StreamWriter writer = new StreamWriter(path))
            {
                while (true)
                {
                    writer.Write(toWrite);
                    count++;
                }
            }
        }
        catch (IOException)
        {                
        }
    
        return string.Format("There used to be {0} bytes available on drive {1}.", count, path);
    }
    
    public static string DriveSizeTotal(string path)
    {
        DeleteAllFiles(path);
        int sizeAvailable = GetAvailableSize(path);
        return string.Format("Drive {0} will hold a total of {1} bytes.", path, sizeAvailable);
    }
    
        4
  •  2
  •   Maksim Sestic    9 年前

    实际上不是一个C示例,但可能会给您一个提示-一个vb.net函数沿指定路径返回驱动器上的可用空间和总空间量(以字节为单位)。也适用于UNC路径,与system.io.driveinfo不同。

    VB.NET:

    <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Private Shared Function GetDiskFreeSpaceEx(lpDirectoryName As String, ByRef lpFreeBytesAvailable As ULong, ByRef lpTotalNumberOfBytes As ULong, ByRef lpTotalNumberOfFreeBytes As ULong) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    
    Public Shared Function GetDriveSpace(folderName As String, ByRef freespace As ULong, ByRef totalspace As ULong) As Boolean
        If Not String.IsNullOrEmpty(folderName) Then
            If Not folderName.EndsWith("\") Then
                folderName += "\"
            End If
    
            Dim free As ULong = 0, total As ULong = 0, dummy2 As ULong = 0
            If GetDiskFreeSpaceEx(folderName, free, total, dummy2) Then
                freespace = free
                totalspace = total
                Return True
            End If
        End If
    End Function
    
        5
  •  1
  •   Ken White    14 年前

    system.io.driveinfo工作正常。我连接到两个单独的Netware服务器,并映射了几个驱动器。

    这是本地C:驱动器:

    Drive C:\
      File type: Fixed
      Volume label: Drive C
      File system: NTFS
      Available space to current user:   158558248960 bytes
      Total available space:             158558248960 bytes
      Total size of drive:               249884004352 bytes 
    

    以下是其中一个网络驱动器的输出:

    Drive F:\
      File type: Network
      Volume label: SYS
      File system: NWFS
      Available space to current user:     1840656384 bytes
      Total available space:               1840656384 bytes
      Total size of drive:                 4124475392 bytes 
    

    我直接从DriveInfo上的msdn docs中使用了以下代码:

    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("  File 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);
                }
            }
        }
    }
    
        6
  •  1
  •   CrazyIvan1974    11 年前

    还有一种可能,我已经用了很多年了。下面的示例是vbscript,但它应该与任何COM感知语言一起工作。注意 GetDrive() 也适用于UNC共享。

    Dim Tripped
    Dim Level
    
    Tripped = False
    Level   = 0
    
    Sub Read(Entry, Source, SearchText, Minimum, Maximum)
    
        Dim fso
        Dim disk
    
        Set fso  = CreateObject("Scripting.FileSystemObject")
    
        Set disk = fso.GetDrive(Source)
    
        Level = (disk.AvailableSpace / (1024 * 1024 * 1024))
    
        If (CDbl(Level) < CDbl(Minimum)) or (CDbl(Level) > CDbl(Maximum)) Then
            Tripped = True
        Else
            Tripped = False
        End If
    
    End Sub
    
        7
  •  1
  •   Herbert    9 年前

    Maksim-Sestic给出了最好的答案,因为它可以在本地和UNC路径上工作。为了更好地处理错误,我稍微修改了他的代码,并包括了一个示例。对我来说就像是一种魅力。

    你需要放

    Imports System.Runtime.InteropServices
    

    在您的代码中,允许识别dllimport。

    以下是修改后的代码:

    <DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Private Shared Function GetDiskFreeSpaceEx(lpDirectoryName As String, ByRef lpFreeBytesAvailable As ULong, ByRef lpTotalNumberOfBytes As ULong, ByRef lpTotalNumberOfFreeBytes As ULong) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    
    Public Shared Function GetDriveSpace(folderName As String, ByRef freespace As ULong, ByRef totalspace As ULong) As Boolean
    
    Dim free As ULong = 0
    Dim total As ULong = 0
    Dim dummy2 As ULong = 0
    
    Try
    
        If Not String.IsNullOrEmpty(folderName) Then
    
             If Not folderName.EndsWith("\") Then
                 folderName += "\"
             End If
    
             If GetDiskFreeSpaceEx(folderName, free, total, dummy2) Then
                 freespace = free
                 totalspace = total
                 Return True
             End If
    
         End If
    
    Catch
    End Try
    
        Return False
    
    End Function
    

    这样称呼:

    dim totalspace as ulong = 0
    dim freespace as ulong = 0
    if GetDriveSpace("\\anycomputer\anyshare", freespace, totalspace) then
        'do what you need to do with freespace and totalspace
    else
        'some error
    end if
    

    foldername也可以是本地目录,例如 drive:\path\path\...

    它仍然在vb.net中,但将其转换为c应该不是问题。

        8
  •  0
  •   Neil N HLGEM    14 年前

    我很肯定这是不可能的。在Windows资源管理器中,如果我尝试获取一个UNC目录的文件夹属性,它就不会给我提供尽可能多的可用空间。已用/可用空间是驱动器的一个特征,而不是文件夹,并且UNC共享仅被视为文件夹。

    您必须:
    -映射驱动器
    -在远程机器上运行一些东西来检查磁盘空间。

    您还可能会遇到分布式文件系统之类的问题,其中一个UNC/映射共享没有绑定到任何特定的驱动器,因此您必须在其中实际总结几个驱动器。

    那么用户配额呢?驱动器可能未满,但您用于写入该文件夹的帐户可能已达到其限制。

        9
  •  0
  •   Mike    13 年前

    不是C,只提供了可用空间,但是。…

    dir \\server\share | find /i "bytes free"
    

    让你成为其中一员。我正在寻找相同的解决方案,但似乎没有一个很好的解决方案-尤其是在试图避免映射驱动器时。