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.

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top