รับพื้นที่ว่างในดิสก์


95

จากอินพุตแต่ละรายการด้านล่างฉันต้องการพื้นที่ว่างในตำแหน่งนั้น สิ่งที่ต้องการ

long GetFreeSpace(string path)

ปัจจัยการผลิต:

c:

c:\

c:\temp

\\server

\\server\C\storage

สำเนาที่แน่นอน: stackoverflow.com/questions/412632
dtb

52
ไม่ซ้ำกัน stackoverflow.com/questions/412632 ถามเกี่ยวกับดิสก์เท่านั้นฉันยังถามเกี่ยวกับเส้นทาง UNC และวิธีแก้ปัญหาใน 412632 ไม่ได้ผลสำหรับพวกเขา
bh213

คำตอบ:


68

นี่ใช้ได้กับฉัน ...

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

โชคดี!


8
drive.TotalFreeSpaceไม่ได้ผลสำหรับฉัน แต่drive.AvailableFreeSpaceทำ
knocte

16
ฉันรู้ว่าคำตอบนี้โบราณ แต่โดยปกติคุณต้องใช้AvailableFreeSpaceตามที่ @knocte บอก AvailableFreeSpaceแสดงจำนวนที่สามารถใช้ได้จริงสำหรับผู้ใช้ (เนื่องจากโควต้า) TotalFreeSpaceแสดงรายการสิ่งที่มีอยู่ในดิสก์โดยไม่คำนึงถึงสิ่งที่ผู้ใช้สามารถใช้ได้
รอยต.

ฉันโหวตความคิดเห็นของ @ RoyT เพราะเขาใช้เวลาอธิบายว่าทำไมถึงแนะนำคนอื่นมากกว่าคนอื่น ๆ
SoCalCoder

41

ข้อมูลโค้ดที่ใช้งานได้โดยใช้GetDiskFreeSpaceExจากลิงค์โดย 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
... if (!GetDiskFreeSpaceEx(folderName, out free, out total, out dummy)) throw new Win32Exception(Marshal.GetLastWin32Error());ฉันอยากจะได้มันกลับมาเป็นโมฆะเช่น ค่อนข้างสะดวกในการค้นหารหัสที่นี่อยู่แล้ว
Eugene Ryabtsev

2
แค่ตรวจสอบ แต่ฉันคิดว่า "CameraStorageFileHelper" เป็นสิ่งประดิษฐ์จากรหัสนี้ที่คัดลอกมาจากต้นฉบับหรือไม่?
Andrew Theken

ไม่จำเป็นต้องลงท้ายด้วย"\\". มันอาจจะเป็นเส้นทาง dir C:ที่มีอยู่หรือแม้เพียงแค่ นี่คือรหัสรุ่นของฉัน: stackoverflow.com/a/58005966/964478
Alex P.

40

DriveInfoจะช่วยให้คุณกับบางส่วนของเหล่านั้น ( แต่มันไม่ได้ทำงานกับเส้นทาง UNC) แต่จริงๆผมคิดว่าคุณจะต้องใช้GetDiskFreeSpaceEx คุณอาจใช้ฟังก์ชันบางอย่างกับ WMI ได้ GetDiskFreeSpaceEx ดูเหมือนจะเป็นทางออกที่ดีที่สุดของคุณ

มีโอกาสที่คุณอาจจะต้องทำความสะอาดเส้นทางของคุณเพื่อให้มันทำงานได้อย่างถูกต้อง


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.
*/

1
แม้ว่ารหัสนี้จะใช้งานได้กับไดรฟ์ทั้งหมดในระบบ แต่ก็ไม่ได้ตอบสนองความต้องการของ OP สำหรับจุดเชื่อมต่อและจุดเชื่อมต่อและการแชร์ ...
Adrian Hum

3

ยังไม่ทดลอง:

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 ผลลัพธ์ของพื้นที่ว่างบน c: \ temp คืออะไร? คุณจะได้รับพื้นที่ว่างของ c: \


5
ดังที่ Kenny กล่าวว่าพื้นที่ว่างสำหรับไดเร็กทอรีใดก็ได้ไม่จำเป็นต้องเหมือนกับพื้นที่ว่างสำหรับไดรฟ์ของไดเร็กทอรีราก ไม่ได้อยู่ในเครื่องของฉันแน่นอน
Barry Kelly

3

นี่คือคำตอบ @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;
    }

วิธีของคุณดีขึ้นเมื่อคุณแยก LastWin32Error
Eddy Shterenberg

3

ลองดูสิ (นี่เป็นวิธีแก้ปัญหาสำหรับฉัน)

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

ดูบทความนี้ !

  1. ระบุเส้นทางของ UNC พาร์หรือโลคัลไดรฟ์โดยค้นหาดัชนีของ ":"

  2. ถ้าเป็น UNC PATH คุณจะแมปเส้นทาง UNC

  3. รหัสสำหรับเรียกใช้ชื่อไดรฟ์คือชื่อไดรฟ์ที่แมป <UNC Mapped Drive หรือ 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. ยกเลิกการแมปหลังจากที่คุณต้องการเสร็จสิ้น


1
แม้ว่ารหัสนี้จะใช้งานได้กับไดรฟ์ทั้งหมดในระบบ แต่ก็ไม่ได้ตอบสนองความต้องการของ OP สำหรับจุดเชื่อมต่อและจุดเชื่อมต่อ ...
Adrian Hum

2

ฉันกำลังมองหาขนาดเป็น GB ดังนั้นฉันจึงเพิ่งปรับปรุงโค้ดจาก Superman ด้านบนด้วยการเปลี่ยนแปลงต่อไปนี้:

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
คุณกำลังส่งคืนความจุทั้งหมดของไดรฟ์
Nick Binnet

3
ฉันคิดว่าใคร ๆ ก็สามารถคำนวณ GB ที่มีไบต์ได้ แต่คุณแสดงให้เห็นว่าผิด รหัส Tis เป็นสิ่งที่ผิดเป็นส่วนการใช้แต่ผลตอบแทนที่ได้ฟังก์ชั่นlong double
Qwertiy

2

ตามคำตอบนี้และ @RichardOD แนะนำคุณควรทำดังนี้:

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

1

ฉันต้องการวิธีการที่คล้ายกันสำหรับโปรเจ็กต์ของฉัน แต่ในกรณีของฉันพา ธ อินพุตมาจากโลคัลดิสก์โวลุ่มหรือวอลุ่มหน่วยเก็บข้อมูลแบบคลัสเตอร์ (CSV) ดังนั้นชั้นเรียน DriveInfo ไม่ได้ผลสำหรับฉัน CSV มีจุดต่อเชื่อมใต้ไดรฟ์อื่นโดยทั่วไปคือ C: \ ClusterStorage \ Volume * โปรดทราบว่า C: จะเป็นโวลุ่มที่แตกต่างจาก C: \ ClusterStorage \ Volume1

นี่คือสิ่งที่ฉันคิดในที่สุด:

    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

คุณสามารถลองสิ่งนี้:

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

โชคดี


2
แม้ว่ารหัสนี้อาจตอบคำถาม แต่การให้บริบทเพิ่มเติมเกี่ยวกับสาเหตุและ / หรือวิธีที่รหัสนี้ตอบคำถามช่วยเพิ่มมูลค่าในระยะยาว
xiawi

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

-1

ฉันมีปัญหาเดียวกันและฉันเห็น waruna manjula ให้คำตอบที่ดีที่สุด อย่างไรก็ตามการเขียนทั้งหมดลงบนคอนโซลไม่ใช่สิ่งที่คุณต้องการ หากต้องการปิดสตริงข้อมูลอัลให้ใช้สิ่งต่อไปนี้

ขั้นตอนที่หนึ่ง: ประกาศค่าเมื่อเริ่มต้น

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

ขั้นตอนที่ 2: รหัสจริง

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

ฉันต้องการทราบว่าคุณสามารถสร้างรหัสความคิดเห็นของคอนโซลเขียนบรรทัดทั้งหมดได้ แต่ฉันคิดว่ามันจะเป็นการดีสำหรับคุณที่จะทดสอบ หากคุณแสดงสิ่งเหล่านี้ทั้งหมดคุณจะได้รับรายชื่อเดียวกันกับ waruna majuna

Drive C: \ Drive type: Fixed Volume label: File system: NTFS Available space to current user: 134880153600 bytes Total available space: 134880153600 bytes Total size of drive: 499554185216 bytes

ไดรฟ์ D: \ ประเภทไดรฟ์: CDRom

Drive H: \ Drive type: Fixed Volume label: HDD File system: NTFS Available space to current user: 2000010817536 bytes Total available space: 2000010817536 bytes ขนาดไดรฟ์ทั้งหมด: 2000263573504 ไบต์

อย่างไรก็ตามตอนนี้คุณสามารถเข้าถึงข้อมูลหลวม ๆ ทั้งหมดได้ที่สตริง


7
ไม่สร้างคลาสสำหรับ 3 วัตถุจำลองและใช้ if อื่น ฉันร้องไห้เล็กน้อย
Mathijs Segers

1
ขออภัยรหัสชุบหม้อน้ำไม่ใช้คอลเลกชันและไม่ใช้สวิตช์?
Adrian Hum
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.