मैं .NET का उपयोग करके बाइट्स संक्षिप्त नाम में मानव-पठनीय फ़ाइल आकार कैसे प्राप्त करूं?
उदाहरण : इनपुट 7,326,629 लें और 6.98 एमबी प्रदर्शित करें
मैं .NET का उपयोग करके बाइट्स संक्षिप्त नाम में मानव-पठनीय फ़ाइल आकार कैसे प्राप्त करूं?
उदाहरण : इनपुट 7,326,629 लें और 6.98 एमबी प्रदर्शित करें
जवाबों:
यह ऐसा करने का सबसे कुशल तरीका नहीं है, लेकिन अगर आप लॉग मैथ्स से परिचित नहीं हैं, तो यह पढ़ना आसान है, और अधिकांश परिदृश्यों के लिए पर्याप्त तेज़ होना चाहिए।
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
समस्या को हल करने के लिए लॉग का उपयोग कर ....
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];
}
C # में भी, लेकिन कन्वर्ट करने के लिए एक स्नैप होना चाहिए। इसके अलावा मैंने पठनीयता के लिए 1 दशमलव स्थान पर गोल किया।
मूल रूप से बेस 1024 में दशमलव स्थानों की संख्या निर्धारित करें और फिर 1024 ^ दशमलव स्थानों से विभाजित करें।
और उपयोग और आउटपुट के कुछ नमूने:
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
संपादित करें: मुझे बताया गया था कि मैंने एक math.floor को याद किया, इसलिए मैंने इसे शामिल किया। (Convert.ToInt32 राउंडिंग का उपयोग करता है, ट्रंकिंग का नहीं और इसीलिए फ्लोर आवश्यक है।) कैच के लिए धन्यवाद।
Edit2: नकारात्मक आकारों और 0 बाइट आकारों के बारे में कुछ टिप्पणियां थीं, इसलिए मैंने उन 2 मामलों को संभालने के लिए अपडेट किया।
double.MaxValue
(स्थान = 102)
अनुरोधित फ़ंक्शन का एक परीक्षण किया गया और काफी अनुकूलित संस्करण यहां पोस्ट किया गया है:
C # मानव पठनीय फ़ाइल आकार - अनुकूलित फ़ंक्शन
सोर्स कोड:
// 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);
कहीं भी मूल्य का उपयोग नहीं करते इसलिए इसे हटा दें। एक और बात, कलाकारों 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();
}
प्रेषक: http://www.pinvoke.net/default.aspx/shlwapi/StrFormatByteSize.html
किसी भी तरह की छोरों के साथ और नकारात्मक आकार के समर्थन के बिना इसे त्वचा के लिए एक और तरीका, (फ़ाइल आकार डेल्टास जैसी चीजों के लिए समझ में आता है):
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);
}
}
चेकआउट बाइट्स लाइब्रेरी। यह हैSystem.TimeSpan
बाइट्स लिए है!
यह आपके लिए रूपांतरण और स्वरूपण को संभालता है।
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");
मैं निम्नलिखित विधि का उपयोग करना पसंद करता हूं (यह टेराबाइट्स का समर्थन करता है, जो ज्यादातर मामलों के लिए पर्याप्त है, लेकिन इसे आसानी से बढ़ाया जा सकता है):
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}";
}
कृपया ध्यान रखें कि यह C # 6.0 (2015) के लिए लिखा गया है, इसलिए इसे पहले के संस्करणों के लिए थोड़ा संपादन की आवश्यकता हो सकती है।
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
या कुछ कर सकते हैं।
यहां एक संक्षिप्त जवाब है जो इकाई को स्वचालित रूप से निर्धारित करता है।
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" बिट के लिए है, "B" बाइट के लिए है और "KMGTPEZY" क्रमशः किलो, मेगा, गिगा, तेरा, पेटा, एक्सा, ज़ेटा और योटा के लिए हैं
एक आईएसओ / IEC80000 खाते में लेने के लिए इसका विस्तार कर सकता है :
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 के बाद: अपने फ्रेंच ( byte
है octet
में फ्रेंच)। किसी भी अन्य भाषा के लिए सिर्फ o
b
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]);
यदि आप Windows Explorer के विवरण में दिखाए अनुसार आकार से मेल खाने का प्रयास कर रहे हैं, तो यह वह कोड है जो आप चाहते हैं:
[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();
}
यह न केवल एक्सप्लोरर से सटीक रूप से मेल खाएगा, बल्कि आपके लिए अनुवादित स्ट्रिंग्स भी प्रदान करेगा और विंडोज संस्करणों में अंतर से मेल खाएगा (उदाहरण के लिए Win10, K = 1000 बनाम पिछले संस्करणों K = 1024)।
सभी समाधानों का मिश्रण :-)
/// <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
}
एक खुला स्रोत परियोजना है जो ऐसा कर सकती है और बहुत कुछ।
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
जैसे @ नेट 3 का समाधान। की श्रेणी का परीक्षण करने के लिए विभाजन के बजाय पाली का उपयोग करें bytes
, क्योंकि विभाजन में अधिक सीपीयू लागत लगती है।
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 बाइट्स" के बजाय "1.4 एमबी" की तलाश कर रहे हैं?
मुझे नहीं लगता कि .NET में ऐसा करने का कोई अंतर्निहित तरीका है। आपको बस यह पता लगाने की आवश्यकता होगी कि कौन सी इकाई उपयुक्त है, और इसे प्रारूपित करें।
संपादित करें: यहाँ कुछ नमूना कोड ऐसा करने के लिए है:
कुछ पुनरावृत्ति के बारे में कैसे:
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");
}
}
तब आप इसे कहते हैं:
return ReturnSize(size, string.Empty);
मेरे 2 सेंट:
string.Format(CultureInfo.CurrentCulture, "{0:0.##} {1}", fileSize, unit);
इसके लायक एक और तरीका है। मुझे ऊपर उल्लिखित @humbads अनुकूलित समाधान पसंद है, इसलिए सिद्धांत की नकल की है, लेकिन मैंने इसे थोड़ा अलग तरीके से लागू किया है।
मुझे लगता है कि यह बहस का विषय है कि क्या यह एक विस्तार विधि होनी चाहिए (क्योंकि सभी लंबे समय तक जरूरी नहीं कि बाइट आकार हो), लेकिन मैं उन्हें पसंद करता हूं, और यह कहीं और है जब मुझे इसकी अगली आवश्यकता हो तो मैं यह तरीका पा सकता हूं!
इकाइयों के बारे में, मुझे नहीं लगता कि मैंने अपने जीवन में कभी y किबिबाइट ’या units मेबिबाइट’ कहा है, और जब मैं विकसित मानकों के बजाय ऐसे लागू होने पर संदेह कर रहा हूं, मुझे लगता है कि यह लंबे समय में भ्रम से बच जाएगा। ।
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);
}
}
मैं मानव पठनीय आकार के स्ट्रिंग में बदलने के लिए नीचे दिए गए लंबे विस्तार विधि का उपयोग करता हूं । यह विधि यहां स्टैक ओवरफ्लो पर पोस्ट किए गए इसी प्रश्न के जावा समाधान का सी # कार्यान्वयन है ।
/// <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";
}