フォルダ(ファイル)サイズを適切な単位に変換する - C#

フォルダ(ファイル)サイズを取得したはイイが、バイトで表示されてもピンとこないので、適切な単位で表示したい。


まず、フォルダサイズを取得します。

/// <summary>
/// フォルダのサイズを取得します
/// </summary>
/// <param name="dirInfo">サイズを取得するフォルダ</param>
/// <returns>フォルダサイズ</returns>
public static long GetFolderSize(string path)
{
    return GetFolderSize(new DirectoryInfo(path));
}

public static long GetFolderSize(DirectoryInfo dirInfo)
{
    long size = 0;

    //フォルダ内のファイルサイズを計算します。
    foreach (FileInfo fi in dirInfo.GetFiles())
    {
        size += fi.Length;
    }

    //サブフォルダのサイズを合計します。
    foreach (DirectoryInfo di in dirInfo.GetDirectories())
    {
        size += GetFolderSize(di);
    }

    return size;
}



取得したサイズを適切な単位に変換します。
string GetFormatSizeString(float size)
{
    return GetFormatSizeString(size, 1024);
}

string GetFormatSizeString(float size, int p)
{
    return GetFormatSizeString(size, p, "#,##0.##");
}

string GetFormatSizeString(float size, int p, string specifier)
{
    string[] suffix = { "", "K", "M", "G", "T", "P", "E", "Z", "Y" };
    int index = 0;

    while (size >= p)
    {
        size /= p;
        index++;
    }

    return string.Format(
        "{0}{1}B",
        size.ToString(specifier),
        index < suffix.Length ? suffix[index] : "-");
}
当分はテラバイト(TB)まであれば十分だろうが念のため、出来る限り単位は付加されるようにしてある。
ulong.MaxValueをこのメソッドで変換すると、"16EB"となるため、これ以上の単位は不要とも思われるが、上の処理では一番大きな単位となる"YB"(ヨタバイト:yottabyte)以上の単位となる場合は"-B"となるようにしている。



Usage
string path = Environment.GetFolderPath(
        Environment.SpecialFolder.MyPictures);

long folderSize = GetFolderSize(path);

Console.WriteLine(folderSize);
Console.WriteLine(SizeFormat(folderSize));

念のため、"ディスク上のサイズ"ではなく、単なる"サイズ"と一致します。



Win APIを使用する


こんな感じでファイルサイズを変換してくれるモノもある。
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
private static extern long StrFormatByteSize(
    long fileSize,
    [MarshalAs(UnmanagedType.LPTStr)] StringBuilder buffer,
    int bufferSize);

public static string GetFormatSizeString(long size)
{
    StringBuilder builder = new StringBuilder(32);
    StrFormatByteSize(size, builder, 32);
    return builder.ToString();
}
しかし、この処理は私が書いた上記の処理よりもパフォーマンスが悪い。
私が調べたところ、処理に掛る時間に約7倍の差が出た。
やはりやってみないと分からないことってありますねぇ。
APIを使ったり、unmanageコードを書けば何でも速くなると思っているアホにはなりたくないからね!!(^-^)v

0 Comments:

Recent Posts