我如何获得一个人类可读的文件大小字节缩写使用。net ?

例子: 输入7,326,629,显示6.98 MB


当前回答

有一个开源项目可以做到这一点,甚至更多。

7.Bits().ToString();         // 7 b
8.Bits().ToString();         // 1 B
(.5).Kilobytes().Humanize();   // 512 B
(1000).Kilobytes().ToString(); // 1000 KB
(1024).Kilobytes().Humanize(); // 1 MB
(.5).Gigabytes().Humanize();   // 512 MB
(1024).Gigabytes().ToString(); // 1 TB

http://humanizr.net/#bytesize

https://github.com/MehdiK/Humanizer

其他回答

int size = new FileInfo( filePath ).Length / 1024;
string humanKBSize = string.Format( "{0} KB", size );
string humanMBSize = string.Format( "{0} MB", size / 1024 );
string humanGBSize = string.Format( "{0} GB", size / 1024 / 1024 );

这里没有什么东西完全符合我的需要,我根据这个线程制作了我自己的,所以这里是我的长扩展,允许您根据标准选择格式要求。

绝对不是最快的,但很灵活。支持EB/EiB。

// <summary>
/// <paramref name="byteCount"/> The original size in bytes ( 8 bits )
/// <paramref name="notationFormat"/> is supported in the following ways:
/// [    'B' / 'b' : Binary :   Kilobyte (KB) is 1024 bytes, Megabyte (MB) is 1048576 bytes, etc    ]
/// [    'I' / 'i' : IEC:       Kibibyte (KiB) is 1024 bytes, Mebibyte (MiB) is 1048576 bytes, etc    ]
/// [    'D' / 'd' : Decimal :  Kilobyte (KB) is 1000 bytes, Megabyte (MB) is 1000000 bytes, etc    ]
/// </summary>

public static string ToDataSizeString( this long byteCount, char notationFormat = 'b' )
{
    char[] supportedFormatChars = { 'b', 'i', 'd' };

    var lowerCaseNotationFormat = char.ToLowerInvariant( notationFormat );

    // Stop shooting holes in my ship!
    if ( !supportedFormatChars.Contains( lowerCaseNotationFormat ) )
    {
        throw new ArgumentException( $"notationFormat argument '{notationFormat}' not supported" );
    }

    long ebLimit = 1152921504606846976;
    long pbLimit = 1125899906842624;
    long tbLimit = 1099511627776;
    long gbLimit = 1073741824;
    long mbLimit = 1048576;
    long kbLimit = 1024;

    var ebSuffix = "EB";
    var pbSuffix = "PB";
    var tbSuffix = "TB";
    var gbSuffix = "GB";
    var mbSuffix = "MB";
    var kbSuffix = "KB";
    var bSuffix  = " B";

    switch ( lowerCaseNotationFormat )
    {
        case 'b':
            // Sweet as
            break;

        case 'i':
            // Limits stay the same, suffixes need changed
            ebSuffix = "EiB";
            pbSuffix = "PiB";
            tbSuffix = "TiB";
            gbSuffix = "GiB";
            mbSuffix = "MiB";
            kbSuffix = "KiB";
            bSuffix  = "  B";
            break;

        case 'd':
            // Suffixes stay the same, limits need changed
            ebLimit = 1000000000000000000;
            pbLimit = 1000000000000000;
            tbLimit = 1000000000000;
            gbLimit = 1000000000;
            mbLimit = 1000000;
            kbLimit = 1000;
            break;

        default:
            // Should have already Excepted, but hey whatever
            throw new ArgumentException( $"notationFormat argument '{notationFormat}' not supported" );

    }

    string fileSizeText;

    // Exa/Exbi sized
    if ( byteCount >= ebLimit )
    {
        fileSizeText = $"{( (double)byteCount / ebLimit ):N1} {ebSuffix}";
    }
    // Peta/Pebi sized
    else if ( byteCount >= pbLimit )
    {
        fileSizeText = $"{( (double)byteCount / pbLimit ):N1} {pbSuffix}";
    }
    // Tera/Tebi sized
    else if ( byteCount >= tbLimit )
    {
        fileSizeText = $"{( (double)byteCount / tbLimit ):N1} {tbSuffix}";
    }
    // Giga/Gibi sized
    else if ( byteCount >= gbLimit )
    {
        fileSizeText = $"{( (double)byteCount / gbLimit ):N1} {gbSuffix}";
    }
    // Mega/Mibi sized
    else if ( byteCount >= mbLimit )
    {
        fileSizeText = $"{( (double)byteCount / mbLimit ):N1} {mbSuffix}";
    }
    // Kilo/Kibi sized
    else if ( byteCount >= kbLimit )
    {
        fileSizeText = $"{( (double)byteCount / kbLimit ):N1} {kbSuffix}";
    }
    // Byte sized
    else
    {
        fileSizeText = $"{byteCount} {bSuffix}";
    }

    return fileSizeText;
}

我使用下面的Long扩展方法将其转换为人类可读的大小字符串。这个方法是在Stack Overflow上发布的相同问题的Java解决方案的c#实现。

/// <summary>
/// Convert a byte count into a human readable size string.
/// </summary>
/// <param name="bytes">The byte count.</param>
/// <param name="si">Whether or not to use SI units.</param>
/// <returns>A human readable size string.</returns>
public static string ToHumanReadableByteCount(
    this long bytes
    , bool si
)
{
    var unit = si
        ? 1000
        : 1024;

    if (bytes < unit)
    {
        return $"{bytes} B";
    }

    var exp = (int) (Math.Log(bytes) / Math.Log(unit));

    return $"{bytes / Math.Pow(unit, exp):F2} " +
           $"{(si ? "kMGTPE" : "KMGTPE")[exp - 1] + (si ? string.Empty : "i")}B";
}

下面是一个Log10的方法:

using System;

class Program {
   static string NumberFormat(double n) {
      var n2 = (int)Math.Log10(n) / 3;
      var n3 = n / Math.Pow(1e3, n2);
      return String.Format("{0:f3}", n3) + new[]{"", " k", " M", " G"}[n2];
   }

   static void Main() {
      var s = NumberFormat(9012345678);
      Console.WriteLine(s == "9.012 G");
   }
}

https://learn.microsoft.com/dotnet/api/system.math.log10

我喜欢使用以下方法(它支持高达tb,这在大多数情况下已经足够了,但它可以很容易地扩展):

private string GetSizeString(long length)
{
    long B = 0, KB = 1024, MB = KB * 1024, GB = MB * 1024, TB = GB * 1024;
    double size = length;
    string suffix = nameof(B);

    if (length >= TB) {
        size = Math.Round((double)length / TB, 2);
        suffix = nameof(TB);
    }
    else if (length >= GB) {
        size = Math.Round((double)length / GB, 2);
        suffix = nameof(GB);
    }
    else if (length >= MB) {
        size = Math.Round((double)length / MB, 2);
        suffix = nameof(MB);
    }
    else if (length >= KB) {
        size = Math.Round((double)length / KB, 2);
        suffix = nameof(KB);
    }

    return $"{size} {suffix}";
}

请记住,这是为c# 6.0(2015)编写的,因此对于较早的版本可能需要进行一些编辑。