我如何获得一个人类可读的文件大小字节缩写使用。net ?
例子: 输入7,326,629,显示6.98 MB
我如何获得一个人类可读的文件大小字节缩写使用。net ?
例子: 输入7,326,629,显示6.98 MB
当前回答
所有溶液的混合:-)
/// <summary>
/// Converts a numeric value into a string that represents the number expressed as a size value in bytes,
/// kilobytes, megabytes, or gigabytes, depending on the size.
/// </summary>
/// <param name="fileSize">The numeric value to be converted.</param>
/// <returns>The converted string.</returns>
public static string FormatByteSize(double fileSize)
{
FileSizeUnit unit = FileSizeUnit.B;
while (fileSize >= 1024 && unit < FileSizeUnit.YB)
{
fileSize = fileSize / 1024;
unit++;
}
return string.Format("{0:0.##} {1}", fileSize, unit);
}
/// <summary>
/// Converts a numeric value into a string that represents the number expressed as a size value in bytes,
/// kilobytes, megabytes, or gigabytes, depending on the size.
/// </summary>
/// <param name="fileInfo"></param>
/// <returns>The converted string.</returns>
public static string FormatByteSize(FileInfo fileInfo)
{
return FormatByteSize(fileInfo.Length);
}
}
public enum FileSizeUnit : byte
{
B,
KB,
MB,
GB,
TB,
PB,
EB,
ZB,
YB
}
其他回答
这可能不是最有效或最优化的方法,但如果您不熟悉对数数学,它更容易阅读,并且对于大多数情况来说应该足够快。
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
double len = new FileInfo(filename).Length;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1) {
order++;
len = len/1024;
}
// Adjust the format string to your preferences. For example "{0:0.#}{1}" would
// show a single decimal place, and no space.
string result = String.Format("{0:0.##} {1}", len, sizes[order]);
我猜你要找的是“1.4 MB”而不是“1468006字节”?
我不认为在。net中有内置的方法来做到这一点。你只需要找出哪个单元是合适的,然后格式化它。
编辑:这里有一些示例代码来做到这一点:
http://www.codeproject.com/KB/cpp/formatsize.aspx
1-liner(加上前缀常量)
const String prefixes = " KMGTPEY";
/// <summary> Returns the human-readable file size for an arbitrary, 64-bit file size. </summary>
public static String HumanSize(UInt64 bytes)
=> Enumerable
.Range(0, prefixes.Length)
.Where(i => bytes < 1024U<<(i*10))
.Select(i => $"{(bytes>>(10*i-10))/1024:0.###} {prefixes[i]}B")
.First();
或者,如果你想减少LINQ对象的分配,使用相同的for循环变量:
/// <summary>
/// Returns the human-readable file size for an arbitrary, 64-bit file size.
/// </summary>
public static String HumanSize(UInt64 bytes)
{
const String prefixes = " KMGTPEY";
for (var i = 0; i < prefixes.Length; i++)
if (bytes < 1024U<<(i*10))
return $"{(bytes>>(10*i-10))/1024:0.###} {prefixes[i]}B";
throw new ArgumentOutOfRangeException(nameof(bytes));
}
下面是@ deepe1的BigInteger版本的答案,它绕过了long的大小限制(因此支持yottabyte和理论上的任何后面的限制):
public static string ToBytesString(this BigInteger byteCount, string format = "N3")
{
string[] suf = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB" };
if (byteCount.IsZero)
{
return $"{0.0.ToString(format)} {suf[0]}";
}
var abs = BigInteger.Abs(byteCount);
var place = Convert.ToInt32(Math.Floor(BigInteger.Log(abs, 1024)));
var pow = Math.Pow(1024, place);
// since we need to do this with integer math, get the quotient and remainder
var quotient = BigInteger.DivRem(abs, new BigInteger(pow), out var remainder);
// convert the remainder to a ratio and add both back together as doubles
var num = byteCount.Sign * (Math.Floor((double)quotient) + ((double)remainder / pow));
return $"{num.ToString(format)} {suf[place]}";
}
另一种皮肤的方法,没有任何类型的循环和负大小支持(对文件大小增量有意义):
public static class Format
{
static string[] sizeSuffixes = {
"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
public static string ByteSize(long size)
{
Debug.Assert(sizeSuffixes.Length > 0);
const string formatTemplate = "{0}{1:0.#} {2}";
if (size == 0)
{
return string.Format(formatTemplate, null, 0, sizeSuffixes[0]);
}
var absSize = Math.Abs((double)size);
var fpPower = Math.Log(absSize, 1000);
var intPower = (int)fpPower;
var iUnit = intPower >= sizeSuffixes.Length
? sizeSuffixes.Length - 1
: intPower;
var normSize = absSize / Math.Pow(1000, iUnit);
return string.Format(
formatTemplate,
size < 0 ? "-" : null, normSize, sizeSuffixes[iUnit]);
}
}
下面是测试套件:
[TestFixture] public class ByteSize
{
[TestCase(0, Result="0 B")]
[TestCase(1, Result = "1 B")]
[TestCase(1000, Result = "1 KB")]
[TestCase(1500000, Result = "1.5 MB")]
[TestCase(-1000, Result = "-1 KB")]
[TestCase(int.MaxValue, Result = "2.1 GB")]
[TestCase(int.MinValue, Result = "-2.1 GB")]
[TestCase(long.MaxValue, Result = "9.2 EB")]
[TestCase(long.MinValue, Result = "-9.2 EB")]
public string Format_byte_size(long size)
{
return Format.ByteSize(size);
}
}