Ответ 1
Как насчет эта ссылка из MSDN, которая использует класс System.IO.DriveInfo
?
Я пытаюсь найти способ определить общее и доступное дисковое пространство в произвольной папке из приложения .NET. Под "общим дисковым пространством" и "доступным дисковым пространством" в папке я ссылаюсь на общее и доступное дисковое пространство, которое эта папка сообщит, если вы выполнили на нем команду "dir", то есть общее и доступное дисковое пространство логический диск, содержащий эту папку, с учетом учетной записи пользователя, под которой выполняется запрос.
Я использую С#. Метод должен работать как для локальных, так и для удаленных папок, указанных как UNC-пути (а не для доступа через сопоставленные буквы дисков). Например, он должен работать для:
Я начинаю с объекта DirectoryInfo, но, похоже, у него нет связанной информации о диске. Класс DriveInfo делает, но он не будет работать с удаленными папками.
Изменить.. После некоторых обменов с вами, ребята, я рассматриваю возможность отображения удаленных папок в качестве локальных дисков, используя DriveInfo для получения данных и повторного разворачивания. Проблема с этим подходом заключается в том, что моему приложению нужно собирать данные для более чем 120 папок несколько раз в день, каждый день. Я не уверен, что это будет возможно.
Любые идеи? Спасибо.
Как насчет эта ссылка из MSDN, которая использует класс System.IO.DriveInfo
?
Вы можете использовать GetDiskFreeSpaceEx из kernel32.dll, который работает с UNC-путями и дисками. Все, что вам нужно сделать, это включить DllImport (см. Ссылку для примера).
Это может быть не то, что вы хотите, но я пытаюсь помочь, и у него есть бонус немного безопасного стирания свободного места вашего диска.
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);
}
Не действительно пример С#, но может дать вам подсказку - функция 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
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
Я использовал следующий код непосредственно из документов MSDN на DriveInfo:
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); } } } }
Вот еще одна возможность, которую я использовал годами. Ниже приведен пример 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
Максим Сестик дал лучший ответ, поскольку он работает как на локальном, так и на 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, но не должен быть проблемой для перевода на С#.
Я уверен, что это невозможно. В проводнике Windows, если я пытаюсь получить свойства папки в каталоге UNC, это не дает мне ничего до доступного пространства. Используемое/доступное пространство является характеристикой для дисков, а не для папок, а общие ресурсы UNC рассматриваются как просто папки.
вам нужно:
- Карта диска
- Запустите что-то на удаленном компьютере, чтобы проверить дисковое пространство.
Вы также можете столкнуться с проблемами с чем-то вроде распределенной файловой системы, в которой UNC/Mapped share НЕ привязан к какому-либо конкретному диску, поэтому вам нужно будет фактически суммировать несколько дисков.
А как насчет пользовательских квот? Возможно, диск не заполнен, но учетная запись, которую вы используете для записи в эту папку, возможно, достигла своего предела.
Не С# и дает только avilable пространство, но.,.
dir \\server\share | find /i "bytes free"
дает вам часть пути. Я ищу или одно и то же решение, но, похоже, не очень приятно - особенно при попытке избежать отображения дисков.