我如何获得一个人类可读的文件大小字节缩写使用。net ?
例子: 输入7,326,629,显示6.98 MB
我如何获得一个人类可读的文件大小字节缩写使用。net ?
例子: 输入7,326,629,显示6.98 MB
当前回答
这个问题很老了,但是一个非常快速的c#函数可以是:
public static string PrettyPrintBytes(long numBytes)
{
if (numBytes < 1024)
return $"{numBytes} B";
if (numBytes < 1048576)
return $"{numBytes / 1024d:0.##} KB";
if (numBytes < 1073741824)
return $"{numBytes / 1048576d:0.##} MB";
if (numBytes < 1099511627776)
return $"{numBytes / 1073741824d:0.##} GB";
if (numBytes < 1125899906842624)
return $"{numBytes / 1099511627776d:0.##} TB";
if (numBytes < 1152921504606846976)
return $"{numBytes / 1125899906842624d:0.##} PB";
return $"{numBytes / 1152921504606846976d:0.##} EB";
}
每次调用只有一次强制转换和一次除法,最多只能进行6次比较。在进行基准测试时,我发现字符串插值比使用string . format()快得多。
其他回答
下面是一个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
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 );
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));
}
为了获得人类可读的字符串,就像用户在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/
下面是@ 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]}";
}