여유 디스크 공간 확보


95

아래의 각 입력을 감안할 때 해당 위치에 여유 공간을 확보하고 싶습니다. 같은 것

long GetFreeSpace(string path)

입력 :

c:

c:\

c:\temp

\\server

\\server\C\storage


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사용자가 사용할 수있는 것에 관계없이 디스크에서 사용할 수있는 것을 나열합니다.
Roy T.

@RoyT의 댓글을 찬성했습니다. 그가 시간을내어 하나가 다른 것보다 추천되는 이유를 설명했기 때문입니다.
SoCalCoder

41

GetDiskFreeSpaceExRichardOD의 링크에서 사용 하는 작업 코드 스 니펫 .

// 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 2013-06-26

2
확인 만했지만 "CameraStorageFileHelper"는 원본에서 복사하여 붙여 넣은이 코드의 인공물이라고 생각합니다.
Andrew Theken 2013-08-13

로 끝날 필요는 없습니다 "\\". 기존의 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 par 또는 로컬 드라이브 경로를 식별합니다.

  2. UNC 경로 인 경우 캠 매핑 UNC 경로

  3. 드라이브 이름을 실행하는 코드는 매핑 된 드라이브 이름 <UNC 매핑 된 드라이브 또는 로컬 드라이브>입니다.

    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 2013-06-21

3
나는 누구나 바이트가있는 GB를 계산할 수 있다고 생각했지만 잘못된 가정임을 보여주었습니다. 나누기가 사용하기 때문에 코드가 잘못 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가 최고의 대답을주는 것을 보았습니다. 그러나 콘솔에 모두 적어 두는 것은 당신이 원하는 것이 아닙니다. 모든 정보에서 문자열을 얻으려면 다음을 사용하십시오.

1 단계 : 시작시 값 선언

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

모든 콘솔 writelines 주석 코드를 만들 수 있다는 점에 유의하고 싶지만 테스트하는 것이 좋을 것이라고 생각했습니다. 이 모든 것을 차례로 표시하면 waruna majuna와 동일한 목록이 표시됩니다.

드라이브 C : \ 드라이브 유형 : 고정 볼륨 레이블 : 파일 시스템 : NTFS 현재 사용자가 사용할 수있는 공간 : 134880153600 바이트 사용 가능한 총 공간 : 134880153600 바이트 드라이브의 총 크기 : 499554185216 바이트

드라이브 D : \ 드라이브 유형 : CDRom

드라이브 H : \ 드라이브 유형 : 고정 볼륨 레이블 : HDD 파일 시스템 : NTFS 현재 사용자가 사용할 수있는 공간 : 2000010817536 바이트 사용 가능한 총 공간 : 2000010817536 바이트 드라이브의 총 크기 : 2000263573504 바이트

그러나 이제 문자열의 모든 느슨한 정보에 액세스 할 수 있습니다.


7
3 개의 시뮬레이션 객체에 대한 클래스를 생성하지 않고 else if를 사용합니다. 나는 조금 울었다.
Mathijs Segers 2017-06-09

1
죄송합니다. 보일러 도금 코드, 컬렉션을 사용하지 않고 스위치를 사용하지 않습니까?
Adrian Hum
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.