Nhận dung lượng đĩa trống


93

Với mỗi đầu vào bên dưới, tôi muốn có được không gian trống trên vị trí đó. Cái gì đó như

long GetFreeSpace(string path)

Đầu vào:

c:

c:\

c:\temp

\\server

\\server\C\storage

Bản sao chính xác: stackoverflow.com/questions/412632
dtb

52
Không phải là bản sao, stackoverflow.com/questions/412632 chỉ hỏi về đĩa, tôi cũng hỏi về đường dẫn UNC và giải pháp trong 412632 không hoạt động với chúng.
bh213

Câu trả lời:


67

cái này phù hợp với tôi ...

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

chúc may mắn!


7
drive.TotalFreeSpacekhông làm việc cho tôi nhưng drive.AvailableFreeSpace
knocte

16
Tôi biết câu trả lời này là cổ xưa, nhưng bạn thường cần sử dụng AvailableFreeSpacenhư @knocte nói. AvailableFreeSpaceliệt kê số lượng thực sự có sẵn cho người dùng (do hạn ngạch). TotalFreeSpaceliệt kê những gì có sẵn trên đĩa, không kể những gì người dùng có thể sử dụng.
Roy T.

Tôi ủng hộ bình luận của @ RoyT vì anh ấy đã dành thời gian để giải thích lý do tại sao cái này được đề xuất hơn cái kia.
SoCalCoder

40

DriveInfo sẽ giúp bạn một số điều đó (nhưng nó không hoạt động với đường dẫn UNC), nhưng thực sự tôi nghĩ bạn sẽ cần sử dụng GetDiskFreeSpaceEx . Bạn có thể đạt được một số chức năng với WMI. GetDiskFreeSpaceEx có vẻ như là lựa chọn tốt nhất của bạn.

Rất có thể bạn sẽ phải dọn dẹp đường dẫn của mình để nó hoạt động bình thường.


40

Làm việc đoạn mã sử dụng GetDiskFreeSpaceExtừ liên kết của 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
Tôi muốn nó trở lại vô hiệu, giống như ... if (!GetDiskFreeSpaceEx(folderName, out free, out total, out dummy)) throw new Win32Exception(Marshal.GetLastWin32Error());. Khá thuận tiện để tìm mã ở đây.
Eugene Ryabtsev

2
Chỉ cần kiểm tra, nhưng tôi nghĩ "CameraStorageFileHelper" là một hiện vật từ mã này được sao chép từ bản gốc?
Andrew Theken

Nó không cần phải kết thúc bằng "\\". Nó có thể là bất kỳ đường dẫn dir hiện có hoặc thậm chí chỉ C:. Đây là phiên bản của tôi về mã này: 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
Trong khi mã này không trong công việc thực tế cho tất cả các ổ đĩa trên hệ thống, nó không giải quyết yêu cầu của OP cho gắn kết điểm và các điểm giao nhau và chia sẻ ...
Adrian Hum

3

chưa được kiểm tra:

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 kết quả của không gian đĩa trống trên c: \ temp là gì? bạn sẽ nhận được không gian trống của c: \


5
Như Kenny nói, dung lượng trống cho bất kỳ thư mục nhất định nào không nhất thiết phải giống như dung lượng trống cho ổ đĩa của thư mục gốc. Chắc chắn không có trên máy của tôi.
Barry Kelly

3

Đây là phiên bản được cấu trúc lại và đơn giản hóa của câu trả lời @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;
    }

Cách của bạn tốt hơn, khi bạn trích xuất LastWin32Error
Eddy Shterenberg

3

Kiểm tra điều này (đây là một giải pháp hiệu quả cho tôi)

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

xem bài viết này !

  1. xác định UNC par hoặc đường dẫn ổ đĩa cục bộ bằng cách tìm kiếm chỉ mục của ":"

  2. nếu nó là UNC PATH bạn cam bản đồ đường dẫn UNC

  3. mã để thực thi tên ổ đĩa là tên ổ đĩa được ánh xạ <UNC Mapped Drive hoặc 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. hủy bản đồ sau khi bạn hoàn thành yêu cầu.


1
Trong khi mã này không trong công việc thực tế cho tất cả các ổ đĩa trên hệ thống, nó không giải quyết yêu cầu của OP cho gắn kết điểm và các điểm giao nhau ...
Adrian Hum

2

Tôi đang tìm kiếm kích thước tính bằng GB, vì vậy tôi vừa cải thiện mã từ Superman ở trên với những thay đổi sau:

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
Bạn đang trả về tổng dung lượng của ổ đĩa.
Nick Binnet

3
Tôi nghĩ rằng bất kỳ ai cũng có thể tính toán GB có byte, nhưng bạn đã chỉ ra rằng đó là giả định sai. Mã Tis sai khi phép chia sử dụng longnhưng hàm trả về double.
Qwertiy

2

Như câu trả lời này và @RichardOD đã đề xuất, bạn nên làm như thế này:

[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

Tôi muốn một phương pháp tương tự cho dự án của mình nhưng trong trường hợp của tôi, các đường dẫn đầu vào là từ các ổ đĩa cục bộ hoặc các ổ đĩa lưu trữ theo cụm (CSV). Vì vậy, lớp DriveInfo không hoạt động đối với tôi. CSV có một điểm gắn kết bên dưới ổ đĩa khác, thường là C: \ ClusterStorage \ Volume *. Lưu ý rằng C: sẽ là một Khối lượng khác với C: \ ClusterStorage \ Volume1

Đây là những gì cuối cùng tôi đã nghĩ ra:

    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

Bạn có thể thử điều này:

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

Chúc may mắn


2
Mặc dù mã này có thể trả lời câu hỏi, nhưng việc cung cấp thêm ngữ cảnh liên quan đến lý do và / hoặc cách mã này trả lời câu hỏi sẽ cải thiện giá trị lâu dài của nó.
xiawi

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

-1

Tôi đã gặp vấn đề tương tự và tôi thấy waruna manjula đưa ra câu trả lời tốt nhất. Tuy nhiên, viết tất cả xuống bảng điều khiển không phải là điều bạn có thể muốn. Để loại bỏ chuỗi thông tin al, hãy sử dụng như sau

Bước một: khai báo các giá trị khi bắt đầu

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

Bước 2: mã thực tế

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

Tôi muốn lưu ý rằng bạn chỉ có thể tạo tất cả mã bình luận của bảng điều khiển writelines, nhưng tôi nghĩ rằng sẽ rất tuyệt khi bạn kiểm tra nó. Nếu bạn hiển thị tất cả những thứ này sau nhau, bạn sẽ có danh sách giống như waruna majuna

Ổ C: \ Loại ổ: Cố định Nhãn ổ đĩa: Hệ thống tệp: NTFS Dung lượng trống cho người dùng hiện tại: 134880153600 byte Tổng dung lượng khả dụng: 134880153600 byte Tổng kích thước ổ đĩa: 499554185216 byte

Ổ D: \ Loại ổ: CDRom

Ổ H: \ Loại ổ: Cố định Nhãn ổ đĩa: HDD Hệ thống tệp: NTFS Dung lượng trống cho người dùng hiện tại: 2000010817536 byte Tổng dung lượng khả dụng: 2000010817536 byte Tổng dung lượng ổ: 2000263573504 byte

Tuy nhiên, bây giờ bạn có thể tích lũy tất cả thông tin lỏng lẻo tại chuỗi


7
Không tạo lớp cho 3 đối tượng mô phỏng và sử dụng if khác. Tôi đã khóc một chút.
Mathijs Segers

1
Xin lỗi mã mạ lò hơi, không sử dụng bộ sưu tập và không sử dụng công tắc?
Adrian Hum
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.