.NET kullanarak bayt kısaltmasında okunabilir dosya boyutunu nasıl alabilirim?
Örnek : 7.326.629 girişini alın ve 6.98 MB'yi görüntüleyin
.NET kullanarak bayt kısaltmasında okunabilir dosya boyutunu nasıl alabilirim?
Örnek : 7.326.629 girişini alın ve 6.98 MB'yi görüntüleyin
Yanıtlar:
Bu, bunu yapmanın en etkili yolu değildir, ancak günlük matematiklerine aşina değilseniz ve çoğu senaryo için yeterince hızlı olması gerektiğinde okumak daha kolaydır.
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]);
The unit was established by the International Electrotechnical Commission (IEC) in 1998 and has been accepted for use by all major standards organizations
sorunu çözmek için Log kullanarak ....
static String BytesToString(long byteCount)
{
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
if (byteCount == 0)
return "0" + suf[0];
long bytes = Math.Abs(byteCount);
int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
double num = Math.Round(bytes / Math.Pow(1024, place), 1);
return (Math.Sign(byteCount) * num).ToString() + suf[place];
}
Ayrıca c #, ancak dönüştürmek için bir çırpıda olması gerekir. Ayrıca okunabilirlik için 1 ondalık basamağa yuvarlandım.
Temel olarak Base 1024'te ondalık basamak sayısını belirleyin ve ardından 1024 ^ ondalık basamaklara bölün.
Ve bazı kullanım ve çıktı örnekleri:
Console.WriteLine(BytesToString(9223372036854775807)); //Results in 8EB
Console.WriteLine(BytesToString(0)); //Results in 0B
Console.WriteLine(BytesToString(1024)); //Results in 1KB
Console.WriteLine(BytesToString(2000000)); //Results in 1.9MB
Console.WriteLine(BytesToString(-9023372036854775807)); //Results in -7.8EB
Düzenleme: Ben bir math.floor özledim dikkat çekti, bu yüzden dahil. (Convert.ToInt32, kesmeyi değil yuvarlamayı kullanır ve bu nedenle Floor gereklidir.) Yakalama için teşekkürler.
Edit2: Negatif boyutlar ve 0 bayt boyutları hakkında birkaç yorum vardı, bu yüzden bu 2 vakayı ele almak için güncelledim.
double.MaxValue
(yer = 102)
İstenen işlevin test edilmiş ve önemli ölçüde optimize edilmiş bir sürümü buraya gönderilir:
C # Okunabilir Dosya Boyutu - Optimize Edilmiş İşlev
Kaynak kodu:
// Returns the human-readable file size for an arbitrary, 64-bit file size
// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB"
public string GetBytesReadable(long i)
{
// Get absolute value
long absolute_i = (i < 0 ? -i : i);
// Determine the suffix and readable value
string suffix;
double readable;
if (absolute_i >= 0x1000000000000000) // Exabyte
{
suffix = "EB";
readable = (i >> 50);
}
else if (absolute_i >= 0x4000000000000) // Petabyte
{
suffix = "PB";
readable = (i >> 40);
}
else if (absolute_i >= 0x10000000000) // Terabyte
{
suffix = "TB";
readable = (i >> 30);
}
else if (absolute_i >= 0x40000000) // Gigabyte
{
suffix = "GB";
readable = (i >> 20);
}
else if (absolute_i >= 0x100000) // Megabyte
{
suffix = "MB";
readable = (i >> 10);
}
else if (absolute_i >= 0x400) // Kilobyte
{
suffix = "KB";
readable = i;
}
else
{
return i.ToString("0 B"); // Byte
}
// Divide by 1024 to get fractional value
readable = (readable / 1024);
// Return formatted number with suffix
return readable.ToString("0.### ") + suffix;
}
double readable = (i < 0 ? -i : i);
hiçbir yerde kullanmazsınız, bu yüzden kaldırın. bir şey daha, oyuncu redaundat
Math.Abs
?
[DllImport ( "Shlwapi.dll", CharSet = CharSet.Auto )]
public static extern long StrFormatByteSize (
long fileSize
, [MarshalAs ( UnmanagedType.LPTStr )] StringBuilder buffer
, int bufferSize );
/// <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="filelength">The numeric value to be converted.</param>
/// <returns>the converted string</returns>
public static string StrFormatByteSize (long filesize) {
StringBuilder sb = new StringBuilder( 11 );
StrFormatByteSize( filesize, sb, sb.Capacity );
return sb.ToString();
}
Gönderen: http://www.pinvoke.net/default.aspx/shlwapi/StrFormatByteSize.html
Herhangi bir döngü olmadan ve negatif boyut desteğiyle (cilt boyutu deltaları gibi şeyler için mantıklı) cilt kaplamanın bir yolu daha:
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]);
}
}
Ve işte test takımı:
[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);
}
}
Ödemeye bytesize kütüphanesi. Bu System.TimeSpan
bayt için!
Dönüştürme ve biçimlendirme işlemlerini sizin için yapar.
var maxFileSize = ByteSize.FromKiloBytes(10);
maxFileSize.Bytes;
maxFileSize.MegaBytes;
maxFileSize.GigaBytes;
Ayrıca dize gösterimi ve ayrıştırma yapar.
// 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");
Aşağıdaki yöntemi kullanmayı seviyorum (çoğu durumda yeterli olan terabayta kadar destekler, ancak kolayca genişletilebilir):
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}";
}
Lütfen bunun C # 6.0 (2015) için yazıldığını unutmayın, bu nedenle önceki sürümler için küçük bir düzenleme yapılması gerekebilir.
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 );
Math.Ceiling
veya benzeri bir şey kullanabilirsiniz.
Üniteyi otomatik olarak belirleyen kısa bir cevap.
public static string ToBytesCount(this long bytes)
{
int unit = 1024;
string unitStr = "b";
if (bytes < unit) return string.Format("{0} {1}", bytes, unitStr);
else unitStr = unitStr.ToUpper();
int exp = (int)(Math.Log(bytes) / Math.Log(unit));
return string.Format("{0:##.##} {1}{2}", bytes / Math.Pow(unit, exp), "KMGTPEZY"[exp - 1], unitStr);
}
"b" bit içindir, "B" Byte içindir ve "KMGTPEZY" sırasıyla kilo, mega, giga, tera, peta, exa, zetta ve yotta içindir
ISO / IEC80000'ü dikkate almak için genişletilebilir :
public static string ToBytesCount(this long bytes, bool isISO = true)
{
int unit = 1024;
string unitStr = "b";
if (!isISO) unit = 1000;
if (bytes < unit) return string.Format("{0} {1}", bytes, unitStr);
else unitStr = unitStr.ToUpper();
if (isISO) unitStr = "i" + unitStr;
int exp = (int)(Math.Log(bytes) / Math.Log(unit));
return string.Format("{0:##.##} {1}{2}", bytes / Math.Pow(unit, exp), "KMGTPEZY"[exp - 1], unitStr);
}
o
KMGTPE sonra: Its fransız ( byte
olan octet
Fransız). Başka bir dil sadece yerini İçin o
ileb
string[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
int s = 0;
long size = fileInfo.Length;
while (size >= 1024)
{
s++;
size /= 1024;
}
string humanReadable = String.Format("{0} {1}", size, suffixes[s]);
Boyutu Windows Gezgini'nin ayrıntı görünümünde gösterildiği gibi eşleştirmeye çalışıyorsanız, istediğiniz kod budur:
[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();
}
Bu, yalnızca Explorer ile tam olarak eşleşmeyecek, aynı zamanda sizin için çevrilen dizeleri ve Windows sürümlerindeki farklılıkları da eşleştirecektir (örneğin Win10, K = 1000 ve önceki K = 1024 sürümlerinde).
Tüm çözeltilerin karışımı :-)
/// <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
}
Bunu ve daha fazlasını yapabilen bir açık kaynak projesi var.
7.Bits().ToString(); // 7 b
8.Bits().ToString(); // 1 B
(.5).Kilobytes().Humanize(); // 512 B
(1000).Kilobytes().ToString(); // 1000 KB
(1024).Kilobytes().Humanize(); // 1 MB
(.5).Gigabytes().Humanize(); // 512 MB
(1024).Gigabytes().ToString(); // 1 TB
@ NET3'ün çözümü gibi. Aralığı test etmek için bölme yerine vardiya kullanın bytes
, çünkü bölme daha fazla CPU maliyeti gerektirir.
private static readonly string[] UNITS = new string[] { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
public static string FormatSize(ulong bytes)
{
int c = 0;
for (c = 0; c < UNITS.Length; c++)
{
ulong m = (ulong)1 << ((c + 1) * 10);
if (bytes < m)
break;
}
double n = bytes / (double)((ulong)1 << (c * 10));
return string.Format("{0:0.##} {1}", n, UNITS[c]);
}
"1468006 bayt" yerine "1,4 MB" aradığınızı varsayalım?
.NET'te bunu yapmanın yerleşik bir yolu olduğunu düşünmüyorum. Sadece hangi birimin uygun olduğunu bulmanız ve biçimlendirmeniz gerekir.
Düzenleme: İşte sadece bunu yapmak için bazı örnek kod:
Bazı özyineleme hakkında:
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");
}
}
O zaman siz söyleyin:
return ReturnSize(size, string.Empty);
2 sentim:
string.Format(CultureInfo.CurrentCulture, "{0:0.##} {1}", fileSize, unit);
Değeri için bir yaklaşım daha. Yukarıda belirtilen @humbads optimize çözümünü beğendim, bu yüzden prensibi kopyaladım, ancak biraz farklı uyguladım.
Bir uzatma yöntemi olup olmadığı konusunda tartışmalı olduğunu düşünüyorum (çünkü her uzunluğun mutlaka bayt boyutları olmadığı için), ancak onları seviyorum ve bir sonraki ihtiyacım olduğunda yöntemi bulabileceğim bir yer!
Birimlerle ilgili olarak, hayatımda hiç 'Kibibyte' veya 'Mebibyte' dediğimi sanmıyorum ve evrimleşmiş standartlardan ziyade böyle zorlananlardan şüphelenirken, uzun vadede karışıklıktan kaçınacağını düşünüyorum .
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);
}
}
Bir insan tarafından okunabilir boyut dizesine dönüştürmek için aşağıdaki Uzun uzatma yöntemini kullanın . Bu yöntem, yığın taşması yayınlanan bu aynı sorunun Java çözümün C # uygulamasıdır burada .
/// <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";
}