15

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

我正在使用 C#。该方法应该适用于以 UNC 路径(而不是通过映射的驱动器号访问)给出的本地和远程文件夹。例如,它应该适用于:

  • C:\温度
  • \\Silfen\Resources\Temp2

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

编辑。与大家交流后,我正在考虑将远程文件夹映射为本地驱动器,使用DriveInfo获取数据,然后再次取消映射。这种方法的问题是我的应用程序需要每天几次收集超过 120 个文件夹的数据。我不确定这是否可行。

有任何想法吗?谢谢。

4

9 回答 9

13

使用该类的 MSDN 链接怎么样?System.IO.DriveInfo

于 2009-11-25T21:18:56.773 回答
12

您可以使用 kernel32.dll 中的 GetDiskFreeSpaceEx,它适用于 UNC 路径和驱动器。您需要做的就是包含一个 DllImport(请参阅链接以获取示例)。

于 2010-03-01T12:41:00.250 回答
4

可能不是您想要的,但我正在努力提供帮助,并且它具有稍微安全地擦除驱动器的可用空间的好处。

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);
}
于 2009-11-25T21:43:32.687 回答
3

不是一个真正的 C# 示例,但可能会给您一个提示 - 一个 VB.NET 函数,它返回指定路径上驱动器上的可用空间和总空间(以字节为单位)。与 System.IO.DriveInfo 不同,也适用于 UNC 路径。

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
于 2015-08-11T21:47:41.043 回答
1

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 文档:

使用系统;
使用 System.IO;

类测试
{
    公共静态无效 Main()
    {
        DriveInfo[] allDrives = DriveInfo.GetDrives();

        foreach(所有驱动器中的 DriveInfo d)
        {
            Console.WriteLine("驱动器 {0}", d.Name);
            Console.WriteLine("文件类型:{0}", d.DriveType);
            如果(d.IsReady == true)
            {
                Console.WriteLine("卷标:{0}", d.VolumeLabel);
                Console.WriteLine("文件系统:{0}", d.DriveFormat);
                Console.WriteLine(
                    " 当前用户的可用空间:{0, 15} 字节",
                    d.AvailableFreeSpace);

                Console.WriteLine(
                    " 总可用空间:{0, 15} 字节",
                    d.总自由空间);

                Console.WriteLine(
                    " 驱动器总大小:{0, 15} 字节",
                    d.总尺寸);
            }
        }
    }
}
于 2009-11-25T21:22:02.103 回答
1

这是我多年来使用的另一种可能性。下面的示例是 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
于 2013-04-23T01:34:58.490 回答
1

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

文件夹名称也可以是本地目录,例如drive:\path\path\...

它仍在 VB.NET 中,但翻译成 C# 应该不成问题。

于 2015-09-14T12:44:22.013 回答
0

我很确定这是不可能的。在 Windows 资源管理器中,如果我尝试获取 UNC 目录的文件夹属性,就可用空间而言,它没有给我任何东西。已用/可用空间是驱动器的特征,而不是文件夹,UNC 共享仅被视为文件夹。

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

您还可能遇到分布式文件系统之类的问题,其中 UNC/Mapped 共享未绑定到任何特定驱动器,因此您必须实际汇总多个驱动器。

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

于 2009-11-25T21:35:37.383 回答
0

不是 C#,只提供可用空间,但是 . . .

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

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

于 2011-04-20T22:03:23.333 回答