web-dev-qa-db-ja.com

ディスクの空き容量を取得する

以下の各入力を考えると、その場所の空き領域を取得したいと思います。何かのようなもの

long GetFreeSpace(string path)

入力:

c:

c:\

c:\temp

\\server

\\server\C\storage
80
bh213

これは私のために働く...

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

幸運を!

53
erez dan

DriveInfo はそれらの一部を支援します(ただしUNCパスでは機能しません)が、実際には GetDiskFreeSpaceEx を使用する必要があると思います。おそらくWMIでいくつかの機能を実現できます。 GetDiskFreeSpaceExはあなたの最善策のように見えます。

おそらく、パスをクリーンアップして適切に機能させる必要があるでしょう。

39
RichardOD

RichardODによるリンクのGetDiskFreeSpaceExを使用した作業コードスニペット。

// 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;
    }
}
35
sasha_gud
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.
*/
6
Waruna Manjula

これを確認してください(これは私にとって実用的なソリューションです)

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
Sachin Nikumbh

未テスト:

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

ところでc:\ tempの空きディスク領域の結果は何ですか? c:\の空きスペースが得られます

2
RvdK

こちらをご覧ください 記事

  1. 「:」のインデックスを検索して、UNCパーまたはローカルドライブパスを識別します

  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. 要件の完了後にマッピング解除します。

2
Siva

プロジェクトで同様の方法が必要でしたが、私の場合、入力パスはローカルディスクボリュームまたはクラスターストレージボリューム(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
varun

この回答 および@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
Alex Jolig

GB単位のサイズを探していたので、次の変更を加えて上記のスーパーマンのコードを改善しました。

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