Holen Sie sich freien Speicherplatz


92

Angesichts der folgenden Eingaben möchte ich an dieser Stelle freien Speicherplatz erhalten. Etwas wie

long GetFreeSpace(string path)

Eingaben:

c:

c:\

c:\temp

\\server

\\server\C\storage


52
Kein Duplikat, stackoverflow.com/questions/412632 fragt nur nach Festplatten, ich frage auch nach UNC-Pfaden und die Lösung in 412632 funktioniert für sie nicht.
Bh213

Antworten:


66

das funktioniert bei mir ...

using System.IO;

private long GetTotalFreeSpace(string driveName)
{
    foreach (DriveInfo drive in DriveInfo.GetDrives())
    {
        if (drive.IsReady && drive.Name == driveName)
        {
            return drive.TotalFreeSpace;
        }
    }
    return -1;
}

Viel Glück!


7
drive.TotalFreeSpacefunktioniert nicht für mich, aber drive.AvailableFreeSpacefunktioniert
knocte

15
Ich weiß, dass diese Antwort uralt ist, aber Sie müssen sie normalerweise verwenden, AvailableFreeSpacewie @knocte sagt. AvailableFreeSpacelistet auf, wie viel tatsächlich für den Benutzer verfügbar ist (aufgrund von Quotierungen). TotalFreeSpacelistet auf, was auf der Festplatte verfügbar ist, unabhängig davon, was der Benutzer verwenden kann.
Roy T.

Ich habe den Kommentar von @ RoyT positiv bewertet, weil er sich die Zeit genommen hat, um zu erklären, warum einer dem anderen empfohlen wird.
SoCalCoder

40

DriveInfo wird Ihnen bei einigen davon helfen (aber es funktioniert nicht mit UNC-Pfaden), aber ich denke wirklich, dass Sie GetDiskFreeSpaceEx verwenden müssen . Mit WMI können Sie wahrscheinlich einige Funktionen erreichen. GetDiskFreeSpaceEx scheint Ihre beste Wahl zu sein.

Wahrscheinlich müssen Sie Ihre Pfade bereinigen, damit es richtig funktioniert.


40

GetDiskFreeSpaceExArbeitscode- Snippet mit dem Link von RichardOD.

// Pinvoke for API function
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
out ulong lpFreeBytesAvailable,
out ulong lpTotalNumberOfBytes,
out ulong lpTotalNumberOfFreeBytes);

public static bool DriveFreeBytes(string folderName, out ulong freespace)
{
    freespace = 0;
    if (string.IsNullOrEmpty(folderName))
    {
        throw new ArgumentNullException("folderName");
    }

    if (!folderName.EndsWith("\\"))
    {
        folderName += '\\';
    }

    ulong free = 0, dummy1 = 0, dummy2 = 0;

    if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2))
    {
        freespace = free;
        return true;
    }
    else
    {
        return false;
    }
}

1
Ich möchte lieber, dass es nichtig zurückkehrt ... if (!GetDiskFreeSpaceEx(folderName, out free, out total, out dummy)) throw new Win32Exception(Marshal.GetLastWin32Error());. Sehr praktisch, um den Code hier trotzdem zu finden.
Eugene Ryabtsev

2
Nur überprüfen, aber ich denke, "CameraStorageFileHelper" ist ein Artefakt aus diesem Code, der vom Original kopiert wird?
Andrew Theken

Es muss nicht mit enden "\\". Es kann ein beliebiger vorhandener Verzeichnispfad sein oder auch nur C:. Hier ist meine Version dieses Codes: stackoverflow.com/a/58005966/964478
Alex P.

7
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("  Drive 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);
            }
        }
    }
}
/* 
This code produces output similar to the following:

Drive A:\
  Drive type: Removable
Drive C:\
  Drive type: Fixed
  Volume label: 
  File system: FAT32
  Available space to current user:     4770430976 bytes
  Total available space:               4770430976 bytes
  Total size of drive:                10731683840 bytes 
Drive D:\
  Drive type: Fixed
  Volume label: 
  File system: NTFS
  Available space to current user:    15114977280 bytes
  Total available space:              15114977280 bytes
  Total size of drive:                25958948864 bytes 
Drive E:\
  Drive type: CDRom

The actual output of this code will vary based on machine and the permissions
granted to the user executing it.
*/

1
Während dieser Code tatsächlich für alle Laufwerke in einem System funktioniert, erfüllt er nicht die Anforderungen des OP an Einhängepunkte und Verbindungspunkte und Freigaben ...
Adrian Hum

3

ungetestet:

using System;
using System.Management;

ManagementObject disk = new
ManagementObject("win32_logicaldisk.deviceid="c:"");
disk.Get();
Console.WriteLine("Logical Disk Size = " + disk["Size"] + " bytes");
Console.WriteLine("Logical Disk FreeSpace = " + disk["FreeSpace"] + "
bytes"); 

Übrigens, was ist das Ergebnis des freien Speicherplatzes auf c: \ temp? Sie erhalten den Speicherplatz frei von c: \


5
Wie Kenny sagt, ist der freie Speicherplatz für ein bestimmtes Verzeichnis nicht unbedingt der gleiche wie der freie Speicherplatz für das Laufwerk des Stammverzeichnisses. Sicherlich nicht auf meiner Maschine.
Barry Kelly

3

Probieren Sie es aus (dies ist eine funktionierende Lösung für mich)

public long AvailableFreeSpace()
{
    long longAvailableFreeSpace = 0;
    try{
        DriveInfo[] arrayOfDrives = DriveInfo.GetDrives();
        foreach (var d in arrayOfDrives)
        {
            Console.WriteLine("Drive {0}", d.Name);
            Console.WriteLine("  Drive type: {0}", d.DriveType);
            if (d.IsReady == true && d.Name == "/data")
            {
                Console.WriteLine("Volume label: {0}", d.VolumeLabel);
                Console.WriteLine("File system: {0}", d.DriveFormat);
                Console.WriteLine("AvailableFreeSpace for current user:{0, 15} bytes",d.AvailableFreeSpace);
                Console.WriteLine("TotalFreeSpace {0, 15} bytes",d.TotalFreeSpace);
                Console.WriteLine("Total size of drive: {0, 15} bytes \n",d.TotalSize);
                }
                longAvailableFreeSpaceInMB = d.TotalFreeSpace;
        }
    }
    catch(Exception ex){
        ServiceLocator.GetInsightsProvider()?.LogError(ex);
    }
    return longAvailableFreeSpace;
}

2

siehe diesen Artikel !

  1. Identifizieren Sie den UNC-Par- oder lokalen Laufwerkspfad, indem Sie den Index ":" suchen.

  2. Wenn es sich um UNC PATH handelt, können Sie den UNC-Pfad der Karte zuordnen

  3. Der Code zum Ausführen des Laufwerksnamens ist der zugeordnete Laufwerksname <UNC Mapped Drive oder Local Drive>.

    using System.IO;
    
    private long GetTotalFreeSpace(string driveName)
    {
    foreach (DriveInfo drive in DriveInfo.GetDrives())
    {
        if (drive.IsReady && drive.Name == driveName)
        {
            return drive.TotalFreeSpace;
        }
    }
    return -1;
    }
  4. Unmap, nachdem Sie die Anforderung erfüllt haben.


1
Dieser Code funktioniert zwar für alle Laufwerke eines Systems, erfüllt jedoch nicht die Anforderungen des OP an Einhängepunkte und Verbindungspunkte ...
Adrian Hum,

2

Ich habe nach der Größe in GB gesucht, also habe ich den Code von Superman oben mit den folgenden Änderungen verbessert:

public double GetTotalHDDSize(string driveName)
{
    foreach (DriveInfo drive in DriveInfo.GetDrives())
    {
        if (drive.IsReady && drive.Name == driveName)
        {
            return drive.TotalSize / (1024 * 1024 * 1024);
        }
    }
    return -1;
}

8
Sie geben die Gesamtkapazität des Laufwerks zurück.
Nick Binnet

3
Ich dachte, dass jeder GB mit Bytes berechnen kann, aber Sie haben gezeigt, dass dies eine falsche Annahme war. Dieser Code ist falsch, da die Division verwendet, longaber die Funktion gibt zurück double.
Qwertiy

2

Als diese Antwort und @RichardOD vorgeschlagen haben, sollten Sie Folgendes tun:

[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
   out ulong lpFreeBytesAvailable,
   out ulong lpTotalNumberOfBytes,
   out ulong lpTotalNumberOfFreeBytes);

ulong FreeBytesAvailable;
ulong TotalNumberOfBytes;
ulong TotalNumberOfFreeBytes;

bool success = GetDiskFreeSpaceEx(@"\\mycomputer\myfolder",
                                  out FreeBytesAvailable,
                                  out TotalNumberOfBytes,
                                  out TotalNumberOfFreeBytes);
if(!success)
    throw new System.ComponentModel.Win32Exception();

Console.WriteLine("Free Bytes Available:      {0,15:D}", FreeBytesAvailable);
Console.WriteLine("Total Number Of Bytes:     {0,15:D}", TotalNumberOfBytes);
Console.WriteLine("Total Number Of FreeBytes: {0,15:D}", TotalNumberOfFreeBytes);

2

Hier ist eine überarbeitete und vereinfachte Version der Antwort von @sasha_gud:

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
        out ulong lpFreeBytesAvailable,
        out ulong lpTotalNumberOfBytes,
        out ulong lpTotalNumberOfFreeBytes);

    public static ulong GetDiskFreeSpace(string path)
    {
        if (string.IsNullOrEmpty(path))
        {
            throw new ArgumentNullException("path");
        }

        ulong dummy = 0;

        if (!GetDiskFreeSpaceEx(path, out ulong freeSpace, out dummy, out dummy))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error());
        }

        return freeSpace;
    }

Ihr Weg ist besser, wenn Sie den LastWin32Error
Eddy Shterenberg

1

Ich wollte eine ähnliche Methode für mein Projekt, aber in meinem Fall stammten die Eingabepfade entweder von lokalen Datenträgern oder von Clustered Storage Volumes (CSVs). Die DriveInfo-Klasse hat bei mir also nicht funktioniert. CSVs haben einen Einhängepunkt unter einem anderen Laufwerk, normalerweise C: \ ClusterStorage \ Volume *. Beachten Sie, dass C: ein anderes Volume als C: \ ClusterStorage \ Volume1 ist

Das habe ich mir endlich ausgedacht:

    public static ulong GetFreeSpaceOfPathInBytes(string path)
    {
        if ((new Uri(path)).IsUnc)
        {
            throw new NotImplementedException("Cannot find free space for UNC path " + path);
        }

        ulong freeSpace = 0;
        int prevVolumeNameLength = 0;

        foreach (ManagementObject volume in
                new ManagementObjectSearcher("Select * from Win32_Volume").Get())
        {
            if (UInt32.Parse(volume["DriveType"].ToString()) > 1 &&                             // Is Volume monuted on host
                volume["Name"] != null &&                                                       // Volume has a root directory
                path.StartsWith(volume["Name"].ToString(), StringComparison.OrdinalIgnoreCase)  // Required Path is under Volume's root directory 
                )
            {
                // If multiple volumes have their root directory matching the required path,
                // one with most nested (longest) Volume Name is given preference.
                // Case: CSV volumes monuted under other drive volumes.

                int currVolumeNameLength = volume["Name"].ToString().Length;

                if ((prevVolumeNameLength == 0 || currVolumeNameLength > prevVolumeNameLength) &&
                    volume["FreeSpace"] != null
                    )
                {
                    freeSpace = ulong.Parse(volume["FreeSpace"].ToString());
                    prevVolumeNameLength = volume["Name"].ToString().Length;
                }
            }
        }

        if (prevVolumeNameLength > 0)
        {
            return freeSpace;
        }

        throw new Exception("Could not find Volume Information for path " + path);
    }

1

Sie können dies versuchen:

var driveName = "C:\\";
var freeSpace = DriveInfo.GetDrives().Where(x => x.Name == driveName && x.IsReady).FirstOrDefault().TotalFreeSpace;

Viel Glück


2
Während dieser Code die Frage möglicherweise beantwortet, verbessert die Bereitstellung eines zusätzlichen Kontexts darüber, warum und / oder wie dieser Code die Frage beantwortet, ihren langfristigen Wert.
Xiawi

var driveName = "C: \\";
Nime Cloud

-1

Ich hatte das gleiche Problem und sah, wie Waruna Manjula die beste Antwort gab. Es ist jedoch nicht das, was Sie möchten, wenn Sie alles auf die Konsole schreiben. Verwenden Sie Folgendes, um die Zeichenfolge von allen Informationen zu entfernen

Schritt eins: Deklarieren Sie die Werte zu Beginn

    //drive 1
    public static string drivename = "";
    public static string drivetype = "";
    public static string drivevolumelabel = "";
    public static string drivefilesystem = "";
    public static string driveuseravailablespace = "";
    public static string driveavailablespace = "";
    public static string drivetotalspace = "";

    //drive 2
    public static string drivename2 = "";
    public static string drivetype2 = "";
    public static string drivevolumelabel2 = "";
    public static string drivefilesystem2 = "";
    public static string driveuseravailablespace2 = "";
    public static string driveavailablespace2 = "";
    public static string drivetotalspace2 = "";

    //drive 3
    public static string drivename3 = "";
    public static string drivetype3 = "";
    public static string drivevolumelabel3 = "";
    public static string drivefilesystem3 = "";
    public static string driveuseravailablespace3 = "";
    public static string driveavailablespace3 = "";
    public static string drivetotalspace3 = "";

Schritt 2: tatsächlicher Code

                DriveInfo[] allDrives = DriveInfo.GetDrives();
                int drive = 1;
                foreach (DriveInfo d in allDrives)
                {
                    if (drive == 1)
                    {
                        drivename = String.Format("Drive {0}", d.Name);
                        drivetype = String.Format("Drive type: {0}", d.DriveType);
                        if (d.IsReady == true)
                        {
                            drivevolumelabel = String.Format("Volume label: {0}", d.VolumeLabel);
                            drivefilesystem = String.Format("File system: {0}", d.DriveFormat);
                            driveuseravailablespace = String.Format("Available space to current user:{0, 15} bytes", d.AvailableFreeSpace);
                            driveavailablespace = String.Format("Total available space:{0, 15} bytes", d.TotalFreeSpace);
                            drivetotalspace = String.Format("Total size of drive:{0, 15} bytes ", d.TotalSize);
                        }
                        drive = 2;
                    }
                    else if (drive == 2)
                    {
                        drivename2 = String.Format("Drive {0}", d.Name);
                        drivetype2 = String.Format("Drive type: {0}", d.DriveType);
                        if (d.IsReady == true)
                        {
                            drivevolumelabel2 = String.Format("Volume label: {0}", d.VolumeLabel);
                            drivefilesystem2 = String.Format("File system: {0}", d.DriveFormat);
                            driveuseravailablespace2 = String.Format("Available space to current user:{0, 15} bytes", d.AvailableFreeSpace);
                            driveavailablespace2 = String.Format("Total available space:{0, 15} bytes", d.TotalFreeSpace);
                            drivetotalspace2 = String.Format("Total size of drive:{0, 15} bytes ", d.TotalSize);
                        }
                        drive = 3;
                    }
                    else if (drive == 3)
                    {
                        drivename3 = String.Format("Drive {0}", d.Name);
                        drivetype3 = String.Format("Drive type: {0}", d.DriveType);
                        if (d.IsReady == true)
                        {
                            drivevolumelabel3 = String.Format("Volume label: {0}", d.VolumeLabel);
                            drivefilesystem3 = String.Format("File system: {0}", d.DriveFormat);
                            driveuseravailablespace3 = String.Format("Available space to current user:{0, 15} bytes", d.AvailableFreeSpace);
                            driveavailablespace3 = String.Format("Total available space:{0, 15} bytes", d.TotalFreeSpace);
                            drivetotalspace3 = String.Format("Total size of drive:{0, 15} bytes ", d.TotalSize);
                        }
                        drive = 4;
                    }
                    if (drive == 4)
                    {
                        drive = 1;
                    }
                }

                //part 2: possible debug - displays in output

                //drive 1
                Console.WriteLine(drivename);
                Console.WriteLine(drivetype);
                Console.WriteLine(drivevolumelabel);
                Console.WriteLine(drivefilesystem);
                Console.WriteLine(driveuseravailablespace);
                Console.WriteLine(driveavailablespace);
                Console.WriteLine(drivetotalspace);

                //drive 2
                Console.WriteLine(drivename2);
                Console.WriteLine(drivetype2);
                Console.WriteLine(drivevolumelabel2);
                Console.WriteLine(drivefilesystem2);
                Console.WriteLine(driveuseravailablespace2);
                Console.WriteLine(driveavailablespace2);
                Console.WriteLine(drivetotalspace2);

                //drive 3
                Console.WriteLine(drivename3);
                Console.WriteLine(drivetype3);
                Console.WriteLine(drivevolumelabel3);
                Console.WriteLine(drivefilesystem3);
                Console.WriteLine(driveuseravailablespace3);
                Console.WriteLine(driveavailablespace3);
                Console.WriteLine(drivetotalspace3);

Ich möchte darauf hinweisen, dass Sie einfach den gesamten Kommentarcode für Konsolenschreiblinien erstellen können, aber ich dachte, es wäre schön, wenn Sie ihn testen würden. Wenn Sie alle diese nacheinander anzeigen, erhalten Sie die gleiche Liste wie Waruna Majuna

Laufwerk C: \ Laufwerkstyp: Feste Datenträgerbezeichnung: Dateisystem: NTFS Verfügbarer Speicherplatz für den aktuellen Benutzer: 134880153600 Byte Gesamter verfügbarer Speicherplatz: 134880153600 Byte Gesamtgröße des Laufwerks: 499554185216 Byte

Laufwerk D: \ Laufwerkstyp: CD-ROM

Laufwerk H: \ Laufwerkstyp: Feste Datenträgerbezeichnung: Festplatte Dateisystem: NTFS Verfügbarer Speicherplatz für den aktuellen Benutzer: 2000010817536 Byte Gesamter verfügbarer Speicherplatz: 2000010817536 Byte Gesamtgröße des Laufwerks: 2000263573504 Byte

Sie können jetzt jedoch auf alle losen Informationen an Strings zugreifen


7
Keine Klasse für 3 ähnliche Objekte erstellen und ein else if verwenden. Ich weinte ein wenig.
Mathijs Segers

1
Entschuldigen Sie den Code für die Kesselbeschichtung, verwenden Sie keine Sammlungen und verwenden Sie keinen Schalter?
Adrian Hum
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.