.NET提供了一个简单的方法将字节转换为KB,MB,GB等?
只是想知道如果.NET提供了一个干净的方式来做到这一点:
int64 x = 1000000; string y = null; if (x / 1024 == 0) { y = x + " bytes"; } else if (x / (1024 * 1024) == 0) { y = string.Format("{0:n1} KB", x / 1024f); }
等等…
这是一个相当简洁的方法来做到这一点:
static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; static string SizeSuffix(Int64 value, int decimalPlaces = 1) { if (decimalPlaces < 0) { throw new ArgumentOutOfRangeException("decimalPlaces"); } if (value < 0) { return "-" + SizeSuffix(-value); } if (value == 0) { return string.Format("{0:n" + decimalPlaces + "} bytes", 0); } // mag is 0 for bytes, 1 for KB, 2, for MB, etc. int mag = (int)Math.Log(value, 1024); // 1L << (mag * 10) == 2 ^ (10 * mag) // [ie the number of bytes in the unit corresponding to mag] decimal adjustedSize = (decimal)value / (1L << (mag * 10)); // make adjustment when the value is large enough that // it would round up to 1000 or more if (Math.Round(adjustedSize, decimalPlaces) >= 1000) { mag += 1; adjustedSize /= 1024; } return string.Format("{0:n" + decimalPlaces + "} {1}", adjustedSize, SizeSuffixes[mag]); }
这是我提出的原始实现,可能会稍微慢一点,但更容易遵循:
static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; static string SizeSuffix(Int64 value, int decimalPlaces = 1) { if (value < 0) { return "-" + SizeSuffix(-value); } int i = 0; decimal dValue = (decimal)value; while (Math.Round(dValue, decimalPlaces) >= 1000) { dValue /= 1024; i++; } return string.Format("{0:n" + decimalPlaces + "} {1}", dValue, SizeSuffixes[i]); } Console.WriteLine(SizeSuffix(100005000L));
检出ByteSize库。 这是字节的System.TimeSpan
!
它处理您的转换和格式。
var maxFileSize = ByteSize.FromKiloBytes(10); maxFileSize.Bytes; maxFileSize.MegaBytes; maxFileSize.GigaBytes;
它也做string表示和parsing。
// 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");
由于其他人发布他们的方法,我想我会张贴我通常使用的扩展方法:
编辑:添加int / long变体…并修复副本错误…
public static class Ext { private const long OneKb = 1024; private const long OneMb = OneKb * 1024; private const long OneGb = OneMb * 1024; private const long OneTb = OneGb * 1024; public static string ToPrettySize(this int value, int decimalPlaces = 0) { return ((long)value).ToPrettySize(decimalPlaces); } public static string ToPrettySize(this long value, int decimalPlaces = 0) { var asTb = Math.Round((double)value / OneTb, decimalPlaces); var asGb = Math.Round((double)value / OneGb, decimalPlaces); var asMb = Math.Round((double)value / OneMb, decimalPlaces); var asKb = Math.Round((double)value / OneKb, decimalPlaces); string chosenValue = asTb > 1 ? string.Format("{0}Tb",asTb) : asGb > 1 ? string.Format("{0}Gb",asGb) : asMb > 1 ? string.Format("{0}Mb",asMb) : asKb > 1 ? string.Format("{0}Kb",asKb) : string.Format("{0}B", Math.Round((double)value, decimalPlaces)); return chosenValue; } }
我会解决它使用Extension methods
, Math.Pow
函数和Enums
:
public static class MyExtension { public enum SizeUnits { Byte, KB, MB, GB, TB, PB, EB, ZB, YB } public static string ToSize(this Int64 value, SizeUnits unit) { return (value / (double)Math.Pow(1024, (Int64)unit)).ToString("0.00"); } }
并使用它像:
string h = x.ToSize(MyExtension.SizeUnits.KB);
不,主要是因为它是一个相当利基的需要,而且有太多可能的变化。 (是“KB”,“Kb”还是“Ko”?是兆字节1024 * 1024字节,还是1024 * 1000字节? – 是的,有些地方使用它!)
答案最多的简短版本有TB值的问题。
我适当调整它也处理tb值,仍然没有一个循环,也添加了一些负值的错误检查。 这是我的解决scheme:
static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" }; static string SizeSuffix(long value, int decimalPlaces = 0) { if (value < 0) { throw new ArgumentException("Bytes should not be negative", "value"); } var mag = (int)Math.Max(0, Math.Log(value, 1024)); var adjustedSize = Math.Round(value / Math.Pow(1024, mag), decimalPlaces); return String.Format("{0} {1}", adjustedSize, SizeSuffixes[mag]); }
这是一个比你更容易扩展的选项,但不是,库本身没有任何内容。
private static List<string> suffixes = new List<string> { " B", " KB", " MB", " GB", " TB", " PB" }; public static string Foo(int number) { for (int i = 0; i < suffixes.Count; i++) { int temp = number / (int)Math.Pow(1024, i + 1); if (temp == 0) return (number / (int)Math.Pow(1024, i)) + suffixes[i]; } return number.ToString(); }
private string GetFileSize(double byteCount) { string size = "0 Bytes"; if (byteCount >= 1073741824.0) size = String.Format("{0:##.##}", byteCount / 1073741824.0) + " GB"; else if (byteCount >= 1048576.0) size = String.Format("{0:##.##}", byteCount / 1048576.0) + " MB"; else if (byteCount >= 1024.0) size = String.Format("{0:##.##}", byteCount / 1024.0) + " KB"; else if (byteCount > 0 && byteCount < 1024.0) size = byteCount.ToString() + " Bytes"; return size; } private void btnBrowse_Click(object sender, EventArgs e) { if (openFile1.ShowDialog() == DialogResult.OK) { FileInfo thisFile = new FileInfo(openFile1.FileName); string info = ""; info += "File: " + Path.GetFileName(openFile1.FileName); info += Environment.NewLine; info += "File Size: " + GetFileSize((int)thisFile.Length); label1.Text = info; } }
这也是一种方法(编号1073741824.0是从1024 * 1024 * 1024又名GB)
我把这里的一些答案合并成了两个很好的方法。 下面的第二种方法将从一个字节string(如1.5.1 GB)转换回字节(如1621350140)作为长types的值。 我希望这对其他人寻找解决scheme将字节转换为string并回到字节是有用的。
public static string BytesAsString(float bytes) { string[] suffix = { "B", "KB", "MB", "GB", "TB" }; int i; double doubleBytes = 0; for (i = 0; (int)(bytes / 1024) > 0; i++, bytes /= 1024) { doubleBytes = bytes / 1024.0; } return string.Format("{0:0.00} {1}", doubleBytes, suffix[i]); } public static long StringAsBytes(string bytesString) { if (string.IsNullOrEmpty(bytesString)) { return 0; } const long OneKb = 1024; const long OneMb = OneKb * 1024; const long OneGb = OneMb * 1024; const long OneTb = OneGb * 1024; double returnValue; string suffix = string.Empty; if (bytesString.IndexOf(" ") > 0) { returnValue = float.Parse(bytesString.Substring(0, bytesString.IndexOf(" "))); suffix = bytesString.Substring(bytesString.IndexOf(" ") + 1).ToUpperInvariant(); } else { returnValue = float.Parse(bytesString.Substring(0, bytesString.Length - 2)); suffix = bytesString.ToUpperInvariant().Substring(bytesString.Length - 2); } switch (suffix) { case "KB": { returnValue *= OneKb; break; } case "MB": { returnValue *= OneMb; break; } case "GB": { returnValue *= OneGb; break; } case "TB": { returnValue *= OneTb; break; } default: { break; } } return Convert.ToInt64(returnValue); }
怎么样:
public void printMB(uint sizekB) { double sizeMB = (double) sizekB / 1024; Console.WriteLine("Size is " + sizeMB.ToString("0.00") + "MB"); }
如打电话就好
printMB(123456);
将导致输出
"Size is 120,56 MB"
没有。
但是你可以像这样执行;
static double ConvertBytesToMegabytes(long bytes) { return (bytes / 1024f) / 1024f; } static double ConvertKilobytesToMegabytes(long kilobytes) { return kilobytes / 1024f; }
另外检查出如何正确转换文件大小以字节为兆或千兆字节?
我去了JerKimballs的解决scheme,并赞成这一点。 不过,我想补充指出,这确实是一个整体争议的问题。 在我的研究中(出于其他原因),我提出了以下几条信息。
当正常的人(我听说他们存在)说千兆字节,他们指的是公制系统,其中1000的幂从原来的字节数= 3千兆字节的数量。 然而,当然有IEC / JEDEC标准很好地总结在维基百科,而不是1000 x的权力,他们有1024.物理存储设备(我想逻辑,如亚马逊和其他)意味着度量与IEC之间的差异越来越大。 因此,例如1 TB == 1 terabyte metric是1000的4次幂,但IEC正式将相似数字定义为1 TiB,tebibyte为1024的4次幂。但是,唉,在非技术性的应用中去观众)规范是衡量标准,并在我自己的应用程序内部使用目前我解释文档的差异。 但为了显示的目的,我什至不提供任何东西,但公制。 在内部,即使它与我的应用程序不相关,我只能存储字节并进行显示计算。
作为一个侧面说明,我发现在.Net框架AFAIK(我常常错误地感谢它的权力),即使在它的4.5版本中,在内部的任何库中都没有包含任何关于这个的东西。 人们会期望某种开源的图书馆在某种程度上是NuGettable,但我承认这是一个小小的秘密。 另一方面System.IO.DriveInfo和其他人也只有字节(很长),这是相当明确的。
https://github.com/logary/logary/blob/master/src/Logary/DataModel.fs#L832-L837
let scaleBytes (value : float) : float * string = let log2 x = log x / log 2. let prefixes = [| ""; "Ki"; "Mi"; "Gi"; "Ti"; "Pi" |] // note the capital K and the 'i' let index = int (log2 value) / 10 1. / 2.**(float index * 10.), sprintf "%s%s" prefixes.[index] (Units.symbol Bytes)
public static class MyExtension { public static string ToPrettySize(this float Size) { return ConvertToPrettySize(Size, 0); } public static string ToPrettySize(this int Size) { return ConvertToPrettySize(Size, 0); } private static string ConvertToPrettySize(float Size, int R) { float F = Size / 1024f; if (F < 1) { switch (R) { case 0: return string.Format("{0:0.00} byte", Size); case 1: return string.Format("{0:0.00} kb", Size); case 2: return string.Format("{0:0.00} mb", Size); case 3: return string.Format("{0:0.00} gb", Size); } } return ConvertToPrettySize(F, ++R); } }
如何recursion:
private static string ReturnSize(double size, string sizeLabel) { if (size > 1024) { if (sizeLabel.Length == 0) return ReturnSize(size / 1024, "KB"); else if (sizeLabel == "KB") return ReturnSize(size / 1024, "MB"); else if (sizeLabel == "MB") return ReturnSize(size / 1024, "GB"); else if (sizeLabel == "GB") return ReturnSize(size / 1024, "TB"); else return ReturnSize(size / 1024, "PB"); } else { if (sizeLabel.Length > 0) return string.Concat(size.ToString("0.00"), sizeLabel); else return string.Concat(size.ToString("0.00"), "Bytes"); } }
那么你可以打电话给它:
ReturnSize(size, string.Empty);