Connaître l'espace disque total et libre dans .NET
Question
Je suis en train de trouver un moyen de déterminer l'espace disque total et disponible dans un dossier arbitraire à partir d'une application .NET. Par « espace disque total » et « l'espace disque disponible » dans un dossier je me réfère à l'espace disque total et disponible que ce dossier ferait rapport si vous avez effectué une commande « dir » à ce sujet, qui est, l'espace disque total et disponible de l'unité logique contenant ce dossier, compte tenu du compte d'utilisateur sous lequel la demande est faite.
J'utilise C #. La méthode devrait fonctionner aussi bien pour les dossiers locaux et distants donnés comme les chemins UNC (plutôt que accessible par lettres de lecteur mappées). Par exemple, il devrait fonctionner pour:
- C: \ Temp
- \\ Silfen \ Resources \ Temp2
Je commence avec un objet DirectoryInfo, mais cela semble avoir aucune information d'espace disque associé. La classe DriveInfo fait, mais il ne fonctionnera pas avec les dossiers à distance.
Modifier. Après quelques échanges avec vous les gars, je considérais la cartographie des dossiers distants comme des lecteurs locaux, en utilisant DriveInfo pour obtenir les données, et encore une fois l'annulation du mappage. Le problème avec cette approche est que mon application a besoin de recueillir les données pour plus de 120 dossiers quelques fois par jour, tous les jours. Je ne suis pas sûr que ce serait possible.
Toutes les idées? Merci.
La solution
Que diriez-vous ce lien de MSDN que les utilisations la classe System.IO.DriveInfo
?
Autres conseils
Vous pouvez utiliser GetDiskFreeSpaceEx de kernel32.dll qui fonctionne avec des chemins UNC et les lecteurs. Tout ce que vous devez faire est de comprendre un DllImport (voir le lien pour un exemple).
peut ne pas être ce que vous voulez, mais je suis en train d'aider, et il a l'avantage de secure légèrement effacer l'espace libre de votre disque.
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);
}
Pas vraiment un exemple C #, mais peut vous donner un indice - une fonction VB.NET retour à la fois quantité d'espace libre et total sur le lecteur (en octets) le long chemin spécifié. Fonctionne pour les chemins UNC, ainsi, à la différence 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 fonctionne très bien. Je suis attaché à deux serveurs Netware séparés, avec plusieurs lecteurs mappés.
Voici le local C: drive:
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
Voici la sortie pour l'un des lecteurs réseau:
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
J'ai utilisé le code suivant, directement à partir de la documentation MSDN sur 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); } } } }
Voici une autre possibilité que je l'ai utilisé pendant des années. L'exemple ci-dessous est VBScript, mais il devrait fonctionner avec tout langage COM-aware. Notez que les travaux de GetDrive()
sur des partages UNC ainsi.
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
Maksim Sestic a donné la meilleure réponse, car il fonctionne sur les deux, les chemins locaux et UNC. J'ai changé son code un peu pour une meilleure gestion des erreurs et inclus un exemple. Fonctionne pour moi comme un charme.
Vous devez mettre
Imports System.Runtime.InteropServices
dans votre code, pour permettre DllImport d'être reconnu.
Voici le code modifié:
<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
Appelez cette façon:
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
Le foldername peut aussi être un répertoire local comme drive:\path\path\...
Il est encore en VB.NET, mais ne devrait pas être un problème pour traduire en C #.
Je suis assez sûr que cela est impossible. Dans l'Explorateur Windows, si je tente d'obtenir les propriétés du dossier d'un répertoire UNC, il ne me donne rien pour autant que l'espace disponible. Espace utilisé / disponible est une caractéristique des lecteurs, et non pas des dossiers et des partages UNC sont traités comme des dossiers seulement.
vous devez soit:
- Carte un lecteur
-. Exécutez quelque chose sur la machine distante pour vérifier l'espace disque
Vous pouvez également rencontrer des problèmes avec quelque chose comme système de fichiers distribué, dans lequel un partage UNC / mappée est lié à aucun lecteur spécifique, donc il youd doivent résumer réellement plusieurs lecteurs.
Et sur les quotas utilisateur? Le lecteur ne peut pas être plein, mais le compte que vous utilisez pour écrire dans ce dossier peut avoir atteint sa limite.
Non C # et ne donne que l'espace avilable, mais. . .
dir \\server\share | find /i "bytes free"
obtient une partie du chemin. Je suis à la recherche ou la même solution, mais il ne semble pas être un agréable un -. Surtout en essayant d'éviter les lecteurs de cartographie