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

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


当前回答

比如@NET3的解决方案。使用shift而不是除法来测试字节的范围,因为除法占用更多的CPU成本。

private static readonly string[] UNITS = new string[] { "B", "KB", "MB", "GB", "TB", "PB", "EB" };

public static string FormatSize(ulong bytes)
{
    int c = 0;
    for (c = 0; c < UNITS.Length; c++)
    {
        ulong m = (ulong)1 << ((c + 1) * 10);
        if (bytes < m)
            break;
    }

    double n = bytes / (double)((ulong)1 << (c * 10));
    return string.Format("{0:0.##} {1}", n, UNITS[c]);
}

其他回答

如果你试图匹配Windows资源管理器的详细信息视图中显示的大小,这是你想要的代码:

[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern long StrFormatKBSize(
    long qdw,
    [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszBuf,
    int cchBuf);

public static string BytesToString(long byteCount)
{
    var sb = new StringBuilder(32);
    StrFormatKBSize(byteCount, sb, sb.Capacity);
    return sb.ToString();
}

这不仅会与资源管理器完全匹配,而且还会为您提供翻译后的字符串,并匹配Windows版本的差异(例如在Win10中,K = 1000 vs.之前的版本K = 1024)。

比如@NET3的解决方案。使用shift而不是除法来测试字节的范围,因为除法占用更多的CPU成本。

private static readonly string[] UNITS = new string[] { "B", "KB", "MB", "GB", "TB", "PB", "EB" };

public static string FormatSize(ulong bytes)
{
    int c = 0;
    for (c = 0; c < UNITS.Length; c++)
    {
        ulong m = (ulong)1 << ((c + 1) * 10);
        if (bytes < m)
            break;
    }

    double n = bytes / (double)((ulong)1 << (c * 10));
    return string.Format("{0:0.##} {1}", n, UNITS[c]);
}

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

绝对不是最快的,但很灵活。支持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;
}

检查我的ByteSize库。这是系统的问题。TimeSpan for bytes!

它为您处理转换和格式化。

var maxFileSize = ByteSize.FromKiloBytes(10);
maxFileSize.Bytes;
maxFileSize.MegaBytes;
maxFileSize.GigaBytes;

它还可以进行字符串表示和解析。

// ToString
ByteSize.FromKiloBytes(1024).ToString(); // 1 MB
ByteSize.FromGigabytes(.5).ToString();   // 512 MB
ByteSize.FromGigabytes(1024).ToString(); // 1 TB

// Parsing
ByteSize.Parse("5b");
ByteSize.Parse("1.55B");

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

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