我如何获得一个人类可读的文件大小字节缩写使用。net ?
例子: 输入7,326,629,显示6.98 MB
我如何获得一个人类可读的文件大小字节缩写使用。net ?
例子: 输入7,326,629,显示6.98 MB
当前回答
我猜你要找的是“1.4 MB”而不是“1468006字节”?
我不认为在。net中有内置的方法来做到这一点。你只需要找出哪个单元是合适的,然后格式化它。
编辑:这里有一些示例代码来做到这一点:
http://www.codeproject.com/KB/cpp/formatsize.aspx
其他回答
检查我的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");
又多了一种方法,不管怎样。我喜欢上面提到的@humbads优化解决方案,所以复制了原理,但我实现了一点不同。
我认为它是否应该是一个扩展方法是有争议的(因为不是所有的long都必须是字节大小),但我喜欢它们,当我下次需要它时,我可以在某个地方找到它!
关于单位,我想我从来没有说过“Kibibyte”或“Mebibyte”,虽然我对这种强制而非进化的标准持怀疑态度,但我认为从长远来看,这将避免混淆。
public static class LongExtensions
{
private static readonly long[] numberOfBytesInUnit;
private static readonly Func<long, string>[] bytesToUnitConverters;
static LongExtensions()
{
numberOfBytesInUnit = new long[6]
{
1L << 10, // Bytes in a Kibibyte
1L << 20, // Bytes in a Mebibyte
1L << 30, // Bytes in a Gibibyte
1L << 40, // Bytes in a Tebibyte
1L << 50, // Bytes in a Pebibyte
1L << 60 // Bytes in a Exbibyte
};
// Shift the long (integer) down to 1024 times its number of units, convert to a double (real number),
// then divide to get the final number of units (units will be in the range 1 to 1023.999)
Func<long, int, string> FormatAsProportionOfUnit = (bytes, shift) => (((double)(bytes >> shift)) / 1024).ToString("0.###");
bytesToUnitConverters = new Func<long,string>[7]
{
bytes => bytes.ToString() + " B",
bytes => FormatAsProportionOfUnit(bytes, 0) + " KiB",
bytes => FormatAsProportionOfUnit(bytes, 10) + " MiB",
bytes => FormatAsProportionOfUnit(bytes, 20) + " GiB",
bytes => FormatAsProportionOfUnit(bytes, 30) + " TiB",
bytes => FormatAsProportionOfUnit(bytes, 40) + " PiB",
bytes => FormatAsProportionOfUnit(bytes, 50) + " EiB",
};
}
public static string ToReadableByteSizeString(this long bytes)
{
if (bytes < 0)
return "-" + Math.Abs(bytes).ToReadableByteSizeString();
int counter = 0;
while (counter < numberOfBytesInUnit.Length)
{
if (bytes < numberOfBytesInUnit[counter])
return bytesToUnitConverters[counter](bytes);
counter++;
}
return bytesToUnitConverters[counter](bytes);
}
}
我猜你要找的是“1.4 MB”而不是“1468006字节”?
我不认为在。net中有内置的方法来做到这一点。你只需要找出哪个单元是合适的,然后格式化它。
编辑:这里有一些示例代码来做到这一点:
http://www.codeproject.com/KB/cpp/formatsize.aspx
这里没有什么东西完全符合我的需要,我根据这个线程制作了我自己的,所以这里是我的长扩展,允许您根据标准选择格式要求。
绝对不是最快的,但很灵活。支持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";
}