मैं .NET का उपयोग करके बाइट्स संक्षिप्त नाम में मानव-पठनीय फ़ाइल आकार कैसे प्राप्त करूं?


279

मैं .NET का उपयोग करके बाइट्स संक्षिप्त नाम में मानव-पठनीय फ़ाइल आकार कैसे प्राप्त करूं?

उदाहरण : इनपुट 7,326,629 लें और 6.98 एमबी प्रदर्शित करें



जवाबों:


353

यह ऐसा करने का सबसे कुशल तरीका नहीं है, लेकिन अगर आप लॉग मैथ्स से परिचित नहीं हैं, तो यह पढ़ना आसान है, और अधिकांश परिदृश्यों के लिए पर्याप्त तेज़ होना चाहिए।

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]);

12
मेरा मानना ​​है कि आप लूप का उपयोग करने के बजाय ऑर्डर को निर्धारित करने के लिए Math.Log का उपयोग कर सकते हैं।
फ्रेंकोइस बोथा

12
इसके अलावा, केबी 1000 बाइट्स है। 1024 बाइट्स KiB है
कांस्टेंटिन

12
@Constantin अच्छी तरह से है जो OS पर निर्भर करता है? विंडोज अभी भी 1024 बाइट्स को 1 KB और 1 MB = 1024 KB के रूप में गिना जाता है, व्यक्तिगत रूप से मैं KiB को खिड़की से बाहर फेंकना चाहता हूं और 1024 का उपयोग करके हर चीज को गिनता हूं? ...
पीटर

4
@Petoj यह OS पर निर्भर नहीं करता है, परिभाषा OS-agnostic है। विकिपीडिया से:The unit was established by the International Electrotechnical Commission (IEC) in 1998 and has been accepted for use by all major standards organizations
ANEves

3
मुझे यह कोड पसंद है क्योंकि यह तेज़ी से चलने लगता है लेकिन मैंने इसे विभिन्न स्थानों की विभिन्न संख्याओं के लिए अनुमति देने के लिए थोड़ा संशोधित किया है। छोटे संख्या में बेहतर 2 दशमलव स्थान दिखाई दे रहे हैं, जैसे 1.38MB जबकि बड़ी संख्या में कम दशमलव की आवश्यकता होती है जैसे 246k या 23.5KB:
Myke Black

321

समस्या को हल करने के लिए लॉग का उपयोग कर ....

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 मामलों को संभालने के लिए अपडेट किया।


7
मैं चेतावनी देना चाहता हूं कि यह जवाब वास्तव में कोड का एक छोटा टुकड़ा है, लेकिन यह सबसे अधिक अनुकूलित नहीं है। मैं चाहूंगा कि आप @humbads द्वारा पोस्ट की गई विधि पर एक नज़र डालें। मैंने दोनों विधियों के माध्यम से 10 000 000 बेतरतीब ढंग से उत्पन्न फ़ाइलों को भेजने के लिए माइक्रोटेस्टिंग चलाया और इससे संख्याएँ आती हैं कि उसकी विधि ~ 30% अधिक तेज है। मैंने हालांकि उनकी विधि की कुछ और सफाई की (असंसदीय कार्य और कास्टिंग)। इसके अलावा मैंने एक नकारात्मक आकार (जब आप फ़ाइलों की तुलना कर रहे हैं) के साथ एक परीक्षण चलाया, जबकि हम्बड्स की विधि इस प्रक्रिया को त्रुटिपूर्ण रूप से संसाधित करती है, यह लॉग विधि एक अपवाद को फेंक देगी!
इवानएल

1
हां, आपको नकारात्मक आकारों के लिए Math.Abs ​​जोड़ना चाहिए। इसके अलावा, कोड केस को संभालता नहीं है यदि आकार बिल्कुल 0. है
dasheddot

Math.Abs, Math.Floor, Math.Log, पूर्णांक में परिवर्तित, Math.Round, Math.Pow, Math.Sign, Add, Multiplying, Dividing? यह गणित के टन नहीं था बस प्रोसेसर पर एक बड़ी कील बनाते हैं। यह शायद @humbads कोड की तुलना में धीमा है
Jayson Ragasa

के लिए विफल double.MaxValue(स्थान = 102)
ब्रूनोएलएम

बहुत अच्छा काम करता है! जिस तरह से विंडोज़ काम करती है (कम से कम मेरे विंडोज 7 अल्टीमेट पर) नकल करने के लिए, Math.ound को Math.Ceiling से बदल दें। एक बार फिर धन्यवाद। मुझे यह समाधान पसंद है।
H_He

101

अनुरोधित फ़ंक्शन का एक परीक्षण किया गया और काफी अनुकूलित संस्करण यहां पोस्ट किया गया है:

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;
}

1
+1! सरल और सीधे आगे! प्रोसेसर आसानी से और तेजी से गणित करता है!
जेसन रगासा

FYI करें, आप double readable = (i < 0 ? -i : i);कहीं भी मूल्य का उपयोग नहीं करते इसलिए इसे हटा दें। एक और बात, कलाकारों redaundat है
Royi Namir

मैंने कलाकारों को हटा दिया, टिप्पणी जोड़ दी, और नकारात्मक संकेत के साथ एक मुद्दा तय किया।
हम्बड्स

बहुत बढ़िया जवाब। धन्यवाद, सिर्फ उपयोग क्यों नहीं Math.Abs?
kspearrin

1
(i <0? -i: i) गणित से लगभग 15% तेज है। एक मिलियन कॉल के लिए, Math.Abs ​​मेरी मशीन पर 0.5 मिलीसेकंड धीमा है - 3.2 एमएस बनाम 3.7 एमएस।
16-02 को 16

72
[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


36
मैं एक noob हो सकता है, लेकिन उस बतख को मारने के लिए पिनवोक के रूप में इस तरह के विशाल तोप का उपयोग करना एक बड़ा दुरुपयोग है।
बार्ट

27
क्या यह खोजकर्ता उपयोग करता है? यदि ऐसा है, तो लोगों को आपके द्वारा दिखाए गए फ़ाइल आकार से मेल खाने के लिए शानदार तरीके से उपयोगी है जो कि एक्सप्लोरर दिखाता है।
एंड्रयू बैकर

8
और एक जो पहिया को सुदृढ़ नहीं करता है
मैथ्यू लॉक

11 अक्षर एक निरंतर सीमा नहीं है और उसके लिए थोड़ा कम है? मेरा मतलब है, अन्य भाषाएं बाइट आकार के संक्षिप्तिकरण, या अन्य स्वरूपण शैलियों के लिए अधिक वर्णों का उपयोग कर सकती हैं।
रे

1
@ बर्ट को नोब्स को इस ज्ञान को सीखने में थोड़ा समय लगता है: "हमें छोटी क्षमताओं के बारे में भूलना चाहिए, समय के बारे में 97% कहना चाहिए: समय से पहले अनुकूलन सभी बुराई की जड़ है" ubiquity.acm.org/article.fm? id = 1513451
मैथ्यू लॉक

22

किसी भी तरह की छोरों के साथ और नकारात्मक आकार के समर्थन के बिना इसे त्वचा के लिए एक और तरीका, (फ़ाइल आकार डेल्टास जैसी चीजों के लिए समझ में आता है):

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);
    }
}

19

चेकआउट बाइट्स लाइब्रेरी। यह है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");

5
यह आपका अपना पुस्तकालय है, नहीं?
लार्सनल

10
इस तरह एक आसान पुस्तकालय में कोई शर्म नहीं है। :-)
लार्सनल

13

मैं निम्नलिखित विधि का उपयोग करना पसंद करता हूं (यह टेराबाइट्स का समर्थन करता है, जो ज्यादातर मामलों के लिए पर्याप्त है, लेकिन इसे आसानी से बढ़ाया जा सकता है):

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) के लिए लिखा गया है, इसलिए इसे पहले के संस्करणों के लिए थोड़ा संपादन की आवश्यकता हो सकती है।


11
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 );

अच्छा उत्तर। फ़ाइल आकार बहुत छोटा होने पर एक समस्या होनी चाहिए, जिस स्थिति में / 1024 रिटर्न 0. आप एक भिन्नात्मक प्रकार का उपयोग कर सकते हैं और कॉल Math.Ceilingया कुछ कर सकते हैं।
नवाफल

10

यहां एक संक्षिप्त जवाब है जो इकाई को स्वचालित रूप से निर्धारित करता है।

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);
}

1
हर कोई सोच रहा के लिए क्यों है वहाँ एक oKMGTPE के बाद: अपने फ्रेंच ( byteहै octetमें फ्रेंच)। किसी भी अन्य भाषा के लिए सिर्फ ob
मैक्स आर।

7
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]);

आपको जांच करनी चाहिए: जबकि (आकार> = 1024 && s <प्रत्यय। गति)।
TcKs

नहीं ... 64-बिट हस्ताक्षरित पूर्णांक ZB से आगे नहीं जा सकता ... जो संख्या 2 ^ 70 का प्रतिनिधित्व करता है।
bobwienholt

7
तो वाईबी में क्यों रखा गया?
विन्यासकर्ता

मुझे यह उत्तर सबसे अच्छा लगता है, लेकिन यहां हर कोई वास्तव में कुशल समाधानों में लगाता है, आपको "आकार = आकार >> 10" का उपयोग करना चाहिए, यह विभाजन की तुलना में बहुत तेज़ है ... और मुझे लगता है कि यह अच्छा है अतिरिक्त ग्रीक विनिर्देशक के पास, क्योंकि निकट भविष्य में, एक सकारात्मक DLR फ़ंक्शन को "लंबे आकार की आवश्यकता नहीं होगी .." आप 128 बिट वेक्टर सीपीयू या कुछ ऐसा हो सकता है जो जेडबी और बड़ा पकड़ सकता है;)
RandomNickName42

4
धातु पर C कोडिंग के दिनों में विभाजन की तुलना में बिटशफ्टिंग अधिक कुशल थी। क्या आपने यह देखने के लिए .NET में एक संपूर्ण परीक्षण किया है कि क्या बिटशिफ्ट वास्तव में अधिक कुशल है? बहुत पहले नहीं, मैंने एक्सोर-स्वैप की स्थिति को देखा और पाया कि यह वास्तव में .NET बनाम एक अस्थायी चर का उपयोग करके धीमा था।
पीट

7

यदि आप 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)।


यह कोड संकलित नहीं करता है, आपको यह निर्दिष्ट करने की आवश्यकता है कि किस फ़ंक्शन से आया है। तो पूरे समारोह प्रोटोटाइप इस तरह लगता है: [DllImport ("shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)] सार्वजनिक स्टेटिक एक्सटर्नल लॉन्ग StrFormatKBSize (लंबी qdw, [MarshalAs (UnmanagedType.LPTStr)] StringBuestone PsBlestone ); मुझे पहले ऐसा होना चाहिए जो इस समाधान का पक्ष लेगा। यदि पहिये का आविष्कार पहले ही किया गया था तो पहिए को फिर से क्यों लगाया जाए? यह सभी C # प्रोग्रामर्स का विशिष्ट दृष्टिकोण है, लेकिन दुर्भाग्यवश C # उन सभी लक्ष्यों तक नहीं पहुँच पाता है, जो C ++ तक पहुँचते हैं।
TarmoPikaro

और एक और बगिफ़िक्स: Int64.MaxValue 9,223,372,036,854,775,807 पर पहुंचता है, जिसे 25+ के बफर आकार को आवंटित करने की आवश्यकता होती है - मैंने इसे केवल 32 मामले में गोल किया है (11 ऊपर डेमो कोड की तरह नहीं)।
TarmoPikaro

धन्यवाद @TarmoPikaro जब मैंने अपने काम करने वाले कोड से कॉपी किया तो मैं DllImport को याद किया। अपनी अनुशंसा के अनुसार बफर आकार भी बढ़ाया। अच्छी पकड़!
मेटलोगिक

प्रभावशाली दृष्टिकोण
tbhaxor 18

यह केवल KB यूनिट दिखाता है। मूल्य के आधार पर सबसे बड़ी इकाई को दिखाने का विचार है।
jstuardo

5

सभी समाधानों का मिश्रण :-)

    /// <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
}

4

एक खुला स्रोत परियोजना है जो ऐसा कर सकती है और बहुत कुछ।

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

http://humanizr.net/#bytesize

https://github.com/MehdiK/Humanizer


3

जैसे @ नेट 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]);
}

2

मुझे लगता है कि आप "1468006 बाइट्स" के बजाय "1.4 एमबी" की तलाश कर रहे हैं?

मुझे नहीं लगता कि .NET में ऐसा करने का कोई अंतर्निहित तरीका है। आपको बस यह पता लगाने की आवश्यकता होगी कि कौन सी इकाई उपयुक्त है, और इसे प्रारूपित करें।

संपादित करें: यहाँ कुछ नमूना कोड ऐसा करने के लिए है:

http://www.codeproject.com/KB/cpp/formatsize.aspx


2

कुछ पुनरावृत्ति के बारे में कैसे:

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);

अच्छा है लेकिन यह
कमलप्रीत

1

मेरे 2 सेंट:

  • किलोबाइट के लिए उपसर्ग kB है (लोअरकेस K)
  • चूंकि ये कार्य प्रस्तुति उद्देश्यों के लिए हैं, इसलिए किसी को संस्कृति की आपूर्ति करनी चाहिए, उदाहरण के लिए: string.Format(CultureInfo.CurrentCulture, "{0:0.##} {1}", fileSize, unit);
  • संदर्भ के आधार पर एक किलोबाइट 1000 या 1024 बाइट्स हो सकता है । वही MB, GB इत्यादि के लिए जाता है।

3
किलोबाइट का मतलब 1000 बाइट्स ( wolframalpha.com/input/?i=kilobyte ) है, यह संदर्भ पर निर्भर नहीं करता है। यह ऐतिहासिक रूप से संदर्भ पर निर्भर करता है, जैसा कि विकिपीडिया कहता है, और यह 1998 में डे ज्यूर बदल गया था और 2005 के आसपास डे वास्तव परिवर्तन शुरू हुआ जब टेराबाइट हार्ड ड्राइव ने इसे लोगों के ध्यान में लाया। 1024 बाइट्स के लिए शब्द kibibyte है। कोड जो उन्हें संस्कृति के आधार पर बदलता है गलत जानकारी का उत्पादन कर रहा है।
18

1

इसके लायक एक और तरीका है। मुझे ऊपर उल्लिखित @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);
    }
}

0

मैं मानव पठनीय आकार के स्ट्रिंग में बदलने के लिए नीचे दिए गए लंबे विस्तार विधि का उपयोग करता हूं । यह विधि यहां स्टैक ओवरफ्लो पर पोस्ट किए गए इसी प्रश्न के जावा समाधान का सी # कार्यान्वयन है

/// <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";
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.