Scoprire spazio totale e libero su disco in .NET
Domanda
Sto cercando di trovare un modo per determinare lo spazio totale e disponibile su disco in una cartella arbitraria da un'applicazione .NET. Con "spazio disco totale" e "spazio su disco disponibile" in una cartella mi riferisco allo spazio totale e disponibile su disco che questa cartella avrebbe riferito se è stata eseguita un comando "dir" su di esso, cioè, lo spazio totale e disponibile su disco di l'unità logica che contiene tale cartella, considerando l'account utente in cui viene effettuata la richiesta.
Sto usando C #. Il metodo dovrebbe funzionare sia per le cartelle locali e remoti dato come percorsi UNC (anziché accede attraverso lettere di unità mappate). Ad esempio, dovrebbe funzionare per:
- C: \ Temp
- \\ Silfen \ Resources \ Temp2
sto iniziando con un oggetto DirectoryInfo, ma questo sembra non avere le informazioni di spazio su disco associato. La classe DriveInfo lo fa, ma non funziona con cartelle remote.
Modifica. Dopo alcuni scambi con voi ragazzi, sto considerando la mappatura cartelle remote come unità locali, utilizzando DriveInfo per ottenere i dati, e unmapping di nuovo. Il problema di questo approccio è che la mia applicazione ha bisogno di raccogliere i dati per più di 120 cartelle di un paio di volte al giorno, tutti i giorni. Io non sono sicuro che questo sarebbe fattibile.
Tutte le idee? Grazie.
Soluzione
Come su questo link da MSDN che usi la classe System.IO.DriveInfo
?
Altri suggerimenti
È possibile utilizzare GetDiskFreeSpaceEx da kernel32.dll che funziona con UNC-percorsi e unità. Tutto quello che devi fare è includere un DllImport (vedi link per un esempio).
Questo possono non essere ciò che si vuole, ma sto cercando di aiutare, e ha il vantaggio di Secure leggermente cancellare lo spazio libero del disco rigido.
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);
}
Non proprio un esempio C #, ma può dare un suggerimento - una funzione VB.NET ritorno sia quantità di spazio libero e totale sul disco (in bytes) lungo percorso specificato. Opere per i percorsi UNC e, a differenza di 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 funziona bene. Mi sono attaccato a due server Netware distinte, con diverse unità mappate.
Ecco per il locale 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
Ecco l'output per una delle unità di rete:
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
Ho usato il seguente codice, direttamente dalla documentazione MSDN su 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); } } } }
Ecco una possibilità in più che ho usato per anni. L'esempio che segue è VBScript, ma dovrebbe funzionare con qualsiasi linguaggio COM-aware. Si noti che le opere GetDrive()
su condivisioni UNC pure.
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 ha dato la migliore risposta, come si lavora su entrambi i percorsi, locali e UNC. Ho cambiato il suo codice un po 'per una migliore gestione degli errori e incluso un esempio. Lavora per me come un fascino.
Hai bisogno di mettere
Imports System.Runtime.InteropServices
nel codice, per consentire DllImport di essere riconosciuto.
Ecco il codice modificato:
<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
Lo chiamano in questo modo:
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
Il nomecartella può anche essere una directory locale come drive:\path\path\...
E 'ancora in VB.NET, ma non dovrebbe essere un problema di tradurre in C #.
Sono abbastanza sicuro che questo è impossibile. In Esplora risorse, se cerco di ottenere le proprietà della cartella di una directory UNC, mi dà niente per quanto riguarda lo spazio disponibile. Usato / spazio disponibile è una caratteristica di unità, non le cartelle e condivisioni UNC vengono trattati come solo le cartelle.
bisogna o:
- un'unità di
-. Eseguire qualcosa sulla macchina remota per controllare lo spazio su disco
Si potrebbe anche incorrere in problemi con qualcosa come file system distribuito, nel quale una condivisione UNC / mappata non è legato ad alcun un'unità specifica, quindi non youd devono riassumere in realtà up più unità.
E per quanto riguarda le quote utente? L'unità non può essere pieno, ma l'account che si utilizza per scrivere in quella cartella può aver colpito il suo limite.
Non C # e solo dà lo spazio avilable, ma. . .
dir \\server\share | find /i "bytes free"
si ottiene un pezzo di strada. Sto cercando o la stessa soluzione, ma non sembra essere un bel uno -. Soprattutto quando si cerca di evitare le unità di mappatura