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

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


当前回答

为了获得人类可读的字符串,就像用户在Windows环境中习惯的那样,你应该使用StrFormatByteSize():

using System.Runtime.InteropServices;

...

private long mFileSize;

[DllImport("Shlwapi.dll", CharSet = CharSet.Auto)]
public static extern int StrFormatByteSize(
    long fileSize,
    [MarshalAs(UnmanagedType.LPTStr)] StringBuilder buffer,
    int bufferSize);
    
public string HumanReadableFileSize
{
    get
    {
        var sb = new StringBuilder(20);
        StrFormatByteSize(mFileSize, sb, 20);
        return sb.ToString();
    }
}

我在这里找到了这个: http://csharphelper.com/blog/2014/07/format-file-sizes-in-kb-mb-gb-and-so-forth-in-c/

其他回答

我喜欢使用以下方法(它支持高达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)编写的,因此对于较早的版本可能需要进行一些编辑。

检查我的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");

我使用下面的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";
}

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

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

如果你试图匹配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)。