Dapatkan ruang disk kosong

95

Mengingat setiap masukan di bawah ini, saya ingin mendapatkan ruang kosong di lokasi itu. Sesuatu seperti

long GetFreeSpace(string path)

Masukan:

c:

c:\

c:\temp

\\server

\\server\C\storage
bh213
sumber
Duplikat persis: stackoverflow.com/questions/412632
dtb
52
Bukan duplikat, stackoverflow.com/questions/412632 hanya bertanya tentang disk, saya juga bertanya tentang jalur UNC dan solusi di 412632 tidak berfungsi untuk mereka.
bh213

Jawaban:

68

ini bekerja untuk saya ...

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;
}

semoga berhasil!

erez dan
sumber
8
drive.TotalFreeSpacetidak bekerja untuk saya, tapi drive.AvailableFreeSpacetidak
knocte
16
Saya tahu jawaban ini kuno, tetapi Anda biasanya perlu menggunakan AvailableFreeSpaceseperti yang dikatakan @knocte. AvailableFreeSpacemencantumkan berapa banyak yang sebenarnya tersedia untuk pengguna (karena quotos). TotalFreeSpacemembuat daftar apa yang tersedia di disk, terlepas dari apa yang dapat digunakan pengguna.
Roy T.
Saya memberi suara positif pada komentar @ RoyT karena dia meluangkan waktu untuk menjelaskan mengapa satu lebih direkomendasikan daripada yang lain.
SoCalCoder
41

Potongan kode kerja menggunakan GetDiskFreeSpaceExfrom link oleh 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;
    }
}
sasha_gud
sumber
1
Aku lebih suka mengembalikannya kosong, seperti ... if (!GetDiskFreeSpaceEx(folderName, out free, out total, out dummy)) throw new Win32Exception(Marshal.GetLastWin32Error());. Cukup nyaman untuk menemukan kode di sini.
Eugene Ryabtsev
2
Hanya memeriksa, tapi menurut saya "CameraStorageFileHelper" adalah artefak dari kode ini yang disalin-tempel dari aslinya?
Andrew Theken
Tidak perlu diakhiri dengan "\\". Ini bisa berupa jalur dir yang ada atau bahkan hanya C:. Ini versi saya dari kode ini: stackoverflow.com/a/58005966/964478
Alex P.
40

DriveInfo akan membantu Anda dengan beberapa di antaranya (tetapi tidak berfungsi dengan jalur UNC), tetapi saya pikir Anda perlu menggunakan GetDiskFreeSpaceEx . Anda mungkin dapat mencapai beberapa fungsionalitas dengan WMI. GetDiskFreeSpaceEx sepertinya taruhan terbaik Anda.

Kemungkinannya adalah Anda mungkin harus membersihkan jalur Anda agar berfungsi dengan benar.

RichardOD
sumber
8
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.
*/
Waruna Manjula
sumber
1
Meskipun kode ini sebenarnya berfungsi untuk semua drive pada suatu sistem, kode ini tidak memenuhi persyaratan OP untuk titik pemasangan dan titik persimpangan dan berbagi ...
Adrian Hum
3

belum dicoba:

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"); 

Btw apa hasil dari ruang disk kosong di c: \ temp? Anda akan mendapatkan ruang kosong dari c: \

RvdK
sumber
5
Seperti yang dikatakan Kenny, ruang kosong untuk direktori tertentu tidak harus sama dengan ruang kosong untuk drive dari direktori root. Tentu saja tidak ada di mesin saya.
Barry Kelly
3

Berikut adalah versi jawaban @sasha_gud yang telah difaktorisasi dan disederhanakan:

    [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;
    }
Alex P.
sumber
Cara Anda lebih baik, mengingat Anda mengekstrak LastWin32Error
Eddy Shterenberg
3

Lihat ini (ini adalah solusi yang berfungsi untuk saya)

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;
}
Sachin Nikumbh
sumber
2

lihat artikel ini !

  1. mengidentifikasi UNC par atau jalur drive lokal dengan mencari indeks ":"

  2. jika UNC PATH Anda memetakan jalur UNC

  3. kode untuk mengeksekusi nama drive dipetakan nama drive <UNC Mapped Drive atau 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 setelah kebutuhan Anda selesai.

Siva
sumber
1
Meskipun kode ini sebenarnya berfungsi untuk semua drive di sistem, kode ini tidak memenuhi persyaratan OP untuk titik pemasangan dan titik persimpangan ...
Adrian Hum
2

Saya mencari ukuran dalam GB, jadi saya baru saja meningkatkan kode dari Superman di atas dengan perubahan berikut:

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;
}
NightlyHakr
sumber
8
Anda mengembalikan kapasitas total drive.
Nick Binnet
3
Saya pikir siapa pun dapat menghitung GB yang memiliki byte, tetapi Anda menunjukkan bahwa asumsi yang salah. Kode ini salah sebagai penggunaan divisi longtetapi fungsi kembali double.
Qwertiy
2

Seperti jawaban ini dan @RichardOD menyarankan, Anda harus melakukan seperti ini:

[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);
Alex Jolig
sumber
1

Saya menginginkan metode serupa untuk proyek saya, tetapi dalam kasus saya jalur input berasal dari volume disk lokal atau volume penyimpanan berkerumun (CSV). Jadi kelas DriveInfo tidak bekerja untuk saya. CSV memiliki titik pemasangan di bawah drive lain, biasanya C: \ ClusterStorage \ Volume *. Perhatikan bahwa C: akan menjadi Volume yang berbeda dari C: \ ClusterStorage \ Volume1

Inilah yang akhirnya saya temukan:

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

Anda dapat mencoba ini:

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

Semoga berhasil

Sepideh I
sumber
2
Meskipun kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang mengapa dan / atau bagaimana kode ini menjawab pertanyaan tersebut meningkatkan nilai jangka panjangnya.
xiawi
var driveName = "C: \\";
Nime Cloud
-1

Saya mengalami masalah yang sama dan saya melihat waruna manjula memberikan jawaban terbaik. Namun menulis semuanya di konsol bukanlah yang Anda inginkan. Untuk menghilangkan string dari al info gunakan yang berikut ini

Langkah satu: nyatakan nilai di awal

    //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 = "";

Langkah 2: kode sebenarnya

                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);

Saya ingin mencatat bahwa Anda hanya dapat membuat semua kode komentar baris tulis konsol, tetapi saya pikir akan menyenangkan bagi Anda untuk mengujinya. Jika Anda menampilkan semua ini setelah satu sama lain, Anda mendapatkan daftar yang sama dengan waruna majuna

Drive C: \ Jenis drive: Label Volume tetap: Sistem file: NTFS Ruang yang tersedia untuk pengguna saat ini: 134880153600 byte Total ruang yang tersedia: 134880153600 byte Total ukuran drive: 499554185216 byte

Drive D: \ Tipe drive: CDRom

Drive H: \ Tipe drive: Label Volume tetap: HDD Sistem file: NTFS Ruang yang tersedia untuk pengguna saat ini: 2000010817536 byte Total ruang yang tersedia: 2000010817536 byte Total ukuran drive: 2000263573504 byte

Namun Anda sekarang dapat mengakses semua informasi longgar di string

john doe
sumber
7
Tidak membuat kelas untuk 3 objek simular dan menggunakan else if. Saya menangis sedikit.
Mathijs Segers
1
Maaf kode pelapisan boiler, tidak menggunakan koleksi dan tidak menggunakan sakelar?
Adrian Hum