2009-11-25 82 views
15

Ich versuche eine Möglichkeit zu finden, den gesamten und verfügbaren Speicherplatz in einem beliebigen Ordner aus einer .NET-App zu ermitteln. Unter "Gesamtspeicherplatz" und "verfügbarer Speicherplatz" in einem Ordner beziehe ich mich auf den gesamten und verfügbaren Speicherplatz, den dieser Ordner melden würde, wenn Sie einen "dir" -Befehl ausführen würden, dh den gesamten und verfügbaren Speicherplatz von das logische Laufwerk, das diesen Ordner enthält, unter Berücksichtigung des Benutzerkontos, unter dem die Anforderung ausgeführt wird.Ermitteln von Gesamt- und freiem Speicherplatz in .NET

Ich benutze C#. Die Methode sollte sowohl für lokale als auch für Remote-Ordner funktionieren, die als UNC-Pfade angegeben sind (und nicht über zugeordnete Laufwerksbuchstaben). Zum Beispiel sollte es funktionieren für:

  • C: \ Temp
  • \\ Silfen \ Resources \ Temp2

ich mit einem Directory Objekt bin ab, aber dies scheint keine zugeordnete Platte zu haben, Rauminformationen. Die DriveInfo-Klasse funktioniert, funktioniert aber nicht mit Remoteordnern.

Bearbeiten. Nach einigem Austausch mit Ihnen erwäge ich, Remote-Ordner als lokale Laufwerke zuzuordnen, DriveInfo zum Abrufen der Daten zu verwenden und die Zuordnung wieder aufzuheben. Das Problem bei diesem Ansatz ist, dass meine App die Daten für mehr als 120 Ordner mehrmals täglich am Tag sammeln muss. Ich bin mir nicht sicher, ob das machbar wäre.

Irgendwelche Ideen? Vielen Dank.

+0

Was meinen Sie mit "verfügbaren Speicherplatz in einem Ordner"? – Manu

+0

Ich denke, er meint, wenn Sie ein Netzlaufwerk zuordnen, möchte er wissen, wie viel freier Speicherplatz auf dem Netzlaufwerk ist. – zimmer62

+0

Bearbeiten, um zu klären ... – CesarGon

Antwort

11

Wie wäre es mit this link from MSDN, die die System.IO.DriveInfo Klasse verwendet?

+1

Wie ich in meiner ursprünglichen Frage sage, funktioniert die Klasse DriveInfo nicht mit Remote-Fodlern. :-) – CesarGon

+0

Sorry CesarGon für mein schlechtes! Meh! :(Jetzt, dass Sie UNC Ordner ... Entschuldigung! – t0mm13b

+0

Hey, kein Problem! – CesarGon

1

System.IO.DriveInfo funktioniert gut. Ich bin an zwei separate Netware-Server angeschlossen, mit mehreren Laufwerken zugeordnet.

Hier ist für die lokale Laufwerk 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 

Hier ist die Ausgabe für einen des Netzlaufwerkes:

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 

ich den folgenden Code verwendet wird, direkt von der MSDN-Dokumentation auf 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); 
      } 
     } 
    } 
} 
+1

Sorry, Ken. Bitte lies meine Frage sorgfältig durch. :-) DriveInfo funktioniert nur auf lokalen Laufwerken, auch wenn diese Remote-Ordnern zugeordnet sind. Ich brauche eine Methode, die UNC-Pfade direkt übernehmen kann, die nicht als lokale Laufwerke zugeordnet sind. Danke für Ihre Mühe. – CesarGon

+1

Ah, ich habe die UNC-Referenz im ursprünglichen Post verfehlt. * Muss * aufmerksamer lesen. Entschuldigung, Cesar. –

+0

Kein Problem; Hilfe wird immer geschätzt. :-) – CesarGon

0

Ich bin mir ziemlich sicher, dass das unmöglich ist. Wenn ich im Windows Explorer versuche, die Ordnereigenschaften eines UNC-Verzeichnisses zu bekommen, gibt es mir nichts, was den verfügbaren Platz betrifft. Der verwendete/verfügbare Speicherplatz ist eine Eigenschaft von Laufwerken, nicht von Ordnern, und UNC-Freigaben werden nur als Ordner behandelt.

Sie müssen entweder:
- ein Laufwerk
- Führen Sie etwas auf dem Remote-Computer, um Speicherplatz zu überprüfen.

Sie könnten auch Probleme mit verteilten Systemen haben, in denen eine UNC/Mapped-Freigabe NICHT an ein bestimmtes Laufwerk gebunden ist, so dass Sie mehrere Laufwerke zusammenfassen müssen.

Und was ist mit Benutzerquoten? Das Laufwerk ist möglicherweise nicht voll, aber das Konto, mit dem Sie in diesen Ordner schreiben, hat möglicherweise sein Limit erreicht.

+1

Danke, Neil. Aber der Windows Explorer in meinem Vista-Rechner kann mir durchaus sagen, wie viel Platz in einem von mir genutzten DFS-Ordner zur Verfügung steht. Es muss einen Weg geben, programmatisch dasselbe zu tun. :-) – CesarGon

+0

Wie genau sehen Sie den verfügbaren Platz im Explorer? –

+0

@Cesar: Aber XP kann nicht. Klicken Sie mit der rechten Maustaste auf den gleichen Ordner (als UNC-Pfad anstelle des zugeordneten Laufwerks). Ich habe vorher gepostet und "Eigenschaften" ausgewählt. Ich erhalte nur die Registerkarte "Allgemein" im Dialogfeld ohne Informationen zum freien Speicherplatz. Stattdessen sehe ich: Typ: Ordner Ziel: \\ Server \ Ordner, Erstellt: (Datum und Uhrzeit), Kommentar: (nichts). Das ist alles, was es gibt ... –

4

Diese kann nicht sein, was Sie wollen, aber ich versuche zu helfen, und es hat den Bonus der leicht sicheren Löschen des freien Speicherplatzes Ihrer Festplatte.

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); 
} 
+1

Das ist großartig, Jeffrey. Haben Sie zufällig eine Version mit eingebautem Flusskondensator? : p – CesarGon

+0

+1 Ich mag es zu überlegen, wie lange das für ein 5-TB-Laufwerk dauern würde, ein Byte nach dem anderen. Spaß. –

+1

+1 für den Vorschlaghammer Vorschlag zum Fliegen fliegen! Wirklich erfinderisch !! :) – Stewbob

11

können Sie GetDiskFreeSpaceEx from kernel32.dll verwenden, die mit UNC-Pfade und Antrieben funktioniert. Alles, was Sie tun müssen, ist ein DllImport (siehe Link für ein Beispiel).

+0

Danke. Genau das habe ich getan. :-) tommieb75 hat es vor über drei Monaten vorgeschlagen! – CesarGon

+0

@CesarGon: Die vorgeschlagene Lösung tommieb75 ist etwas anders, weil sie WMI-Objekte (Windows Management Info) verwendet. Das Ergebnis ist das gleiche, aber Sie benötigen unterschiedliche Sicherheitseinstellungen, um WMI-Objekte abzufragen. Auf der anderen Seite benötigt DllImport auch bestimmte Sicherheitseinstellungen, also hängt alles von Ihrer aktuellen Umgebung ab. Beide Lösungen können funktionieren und gültige Ergebnisse liefern. Ich habe gerade diese Lösung für andere Entwickler hinzugefügt, um die Alternative zu sehen. –

+0

tommieb75 hat seiner ersten Antwort einige Kommentare hinzugefügt. In seinen Kommentaren fügt er eine Verknüpfung zu einer Seite hinzu, die explizit zeigt, wie GetDiskFreeSpaceEx() verwendet wird, um den gesamten und freien Speicherplatz zu erhalten. Dies ist die Lösung, die ich implementiert habe, und das ist die Lösung, für die ich seine Antwort vor Monaten angenommen habe. Tut mir leid, wenn ich vorher nicht klar war. :-) – CesarGon

-1

Nicht C# und gibt nur den verfügbaren Platz, aber. . .

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

bekommt Sie einen Teil des Weges. Ich suche oder die gleiche Lösung, aber es scheint nicht ein netter zu sein - besonders wenn man versucht, Laufwerke zu mappen.

1

Hier ist eine weitere Möglichkeit, die ich seit Jahren verwendet habe. Das folgende Beispiel ist VBScript, aber es sollte mit jeder COM-aware Sprache funktionieren. Beachten Sie, dass GetDrive() auch auf UNC-Freigaben funktioniert.

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 
+0

Bitte geben Sie einen Kommentar ein, sollten Sie sich für die Abstimmung entscheiden. Und wieder, das ist ** OLD ** Code. Es gibt viele neuere Techniken. – CrazyIvan1974

+0

Vielleicht, weil es in VB statt C# ist; aber weil ich es hasse, mich anonym anzumelden, habe ich es aufgestuft, um es wieder auf den Boden zu bringen. –

+0

Das ist nicht das, was ich gesucht habe, aber es ist ziemlich nah an dem, was ich brauche, also danke. =) – Skotte

2

Nicht wirklich ein C# Beispiel, aber Sie können einen Hinweis geben - eine VB.NET Funktion sowohl des freien und gesamten Speicherplatz auf Laufwerk zurückkehrt (in Bytes) entlang angegebenen Pfad. Funktioniert auch für UNC-Pfade, im Gegensatz zu 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 
1

Maksim Sestic hat die beste Antwort gegeben, wie es auf beiden, lokalen und UNC-Pfade funktioniert. Ich habe seinen Code für eine bessere Fehlerbehandlung ein wenig geändert und ein Beispiel hinzugefügt. Funktioniert für mich wie ein Zauber.

Sie benötigen

Imports System.Runtime.InteropServices 

in Ihren Code zu setzen, DllImport zu ermöglichen, erkannt werden. Hier

ist der modifizierte Code:

<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 

Nennen Sie es auf diese Weise:

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 

Der Ordnername auch ein lokales Verzeichnis wie drive:\path\path\... sein kann

Es ist immer noch in VB.NET aber sollte kein Problem sein, in C# zu übersetzen.

Verwandte Themen