.NET을 사용하여 사람이 읽을 수있는 파일 크기를 바이트 약어로 얻으려면 어떻게해야합니까?


답변:


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
while 루프를 사용하는 대신 Math.Log를 사용하여 순서를 결정할 수 있다고 생각합니다.
Francois Botha

12
또한 KB는 1000 바이트입니다. 1024 바이트는 KiB 입니다.
Constantin

13
@ OS에 따라 다릅니다. Windows는 여전히 1024 바이트를 1KB, 1MB = 1024KB로 계산합니다. 개인적으로 KiB를 창 밖으로 내 보낸 다음 1024를 사용하여 모든 것을 계산
Peter

4
@Petoj는 OS에 의존하지 않으며 정의는 OS에 구애받지 않습니다. Wikipedia에서 :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
더 빨리 실행되는 것처럼 코드를 선호하지만 소수의 소수점 이하 자릿수를 허용하도록 약간 수정했습니다. 작은 숫자는 소수점 이하 두 자리 (예 : 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 자리로 반올림했습니다.

기본적으로 Base 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 바이트 크기에 대한 몇 가지 의견이 있었 으므로이 두 가지 경우를 처리하도록 업데이트되었습니다.


7
이 답변은 실제로 짧은 코드이지만 가장 최적화되지 않았다는 것을 경고하고 싶습니다. @humbads가 게시 한 방법을 살펴 보시기 바랍니다. 나는 두 가지 방법을 통해 무작위로 생성 된 10 만개의 파일 크기를 보내는 마이크로 테스팅을 실행했으며 그의 방법이 ~ 30 % 빠릅니다. 그러나 그의 방법을 좀 더 청소했습니다 (불필요한 과제 및 캐스팅). 또한 humbads 메서드 가이 처리 방법을 완벽하게 처리하는 동안 음수 크기로 테스트를 실행했습니다 (파일을 비교할 때).이 Log 메서드는 예외를 throw합니다!
IvanL

1
네, 음수 크기의 경우 Math.Abs를 추가해야합니다. 또한 크기가 정확히 0 인 경우 코드는 경우를 처리하지 않습니다.
dasheddot

Math.Abs, Math.Floor, Math.Log, 정수로 변환, Math.Round, Math.Pow, Math.Sign, 추가, 곱하기, 나누기? 이 수 많은 수학이 프로세서에 엄청난 스파이크가되지는 않았습니다. 이 @humbads 코드보다 아마 느립니다
제이슨 Ragasa

실패 double.MaxValue(장소 = 102)
BrunoLM

잘 작동합니다! 윈도우가 작동하는 방식을 모방하려면 (적어도 내 Windows 7 Ultimate에서는) Math.Round를 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! 더 간단하고 똑바로! 프로세서가 수학을 쉽고 빠르게 수행하도록합니다!
Jayson Ragasa

참고로, double readable = (i < 0 ? -i : i);어디에서나 값을 사용하지 않으므로 제거하십시오. 한 가지 더, 캐스트는 redaundat
Royi Namir

캐스트를 제거하고 댓글을 추가하고 음수 부호 문제를 해결했습니다.
humbads

좋은 대답입니다. 고마워, 왜 그냥 사용하지 Math.Abs?
kspearrin

1
(i <0? -i : i)는 Math.Abs보다 약 15 % 빠릅니다. 백만 건의 호출에서 Math.Abs는 내 컴퓨터에서 3.2 밀리 대 3.7 밀리 초로 0.5 밀리 초 느립니다.
humbads

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
나는 멍청한 것 일지 모르지만 오리를 죽이기 위해 pinvoke와 같은 거대한 대포를 사용하는 것은 큰 오용입니다.
Bart

27
이것이 탐색기가 사용하는 것입니까? 그렇다면 사람들이 사용자가 표시하는 파일 크기를 탐색기에 표시되는 파일 크기와 일치시키는 데 매우 유용합니다.
Andrew Backer

8
그리고 바퀴를 재발 명하지 않는 것
Matthew Lock

11 문자가 상수 제한이 아니고 조금 낮습니까? 다른 언어는 바이트 크기 약어 또는 다른 서식 스타일에 더 많은 문자를 사용할 수 있습니다.
Ray

1
@Bart 멍청한 놈들이 이것에 대한 지혜를 배우는 데는 시간이 걸린다 : "우리는 시간의 97 % 정도의 작은 효율성을 잊어야한다 : 조기 최적화는 모든 악의 근원" ubiquity.acm.org/article.cfm? id = 1513451
Matthew Lock

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

체크 아웃 ByteSize의 라이브러리를. 그것은이다 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
그것은 당신 만의 도서관입니다.
Larsenal

10
이와 같은 편리한 라이브러리에는 부끄러움이 없습니다. :-)
Larsenal

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또는 다른 것을 사용할 수 있습니다 .
nawfal

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"는 각각 킬로, 메가, 기가, 테라, 페타, 엑사, 제타 및 요타를 나타냅니다.

ISO / 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프랑스어). 다른 언어의 o경우 다음을b
Max R로

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

while (size> = 1024 && s <suffixes.Length)를 확인해야합니다.
TcKs November

nope ... 64 비트 부호있는 정수는 ZB를 넘어서는 안됩니다 ... 숫자는 2 ^ 70을 나타냅니다.
bobwienholt

7
왜 YB에 넣을까요?
구성자

나는이 답변이 가장 마음에 들지만, 여기에있는 모든 사람들이 정말로 비효율적 인 솔루션을 사용하고 있다면, "size = size >> 10"시프트를 사용하는 것이 나누기보다 훨씬 빠르다. 가까운 미래에, 가능한 DLR 함수가 "긴 크기"를 필요로하지 않기 때문에 여분의 그리스어 지정자가 있습니다. 128 비트 벡터 CPU 또는 ZB 이상을 수용 할 수있는 무언가에있을 수 있습니다.)
RandomNickName42

4
비트 시프 팅은 금속의 C 코딩 시대에 나누기보다 더 효율적이었습니다. 비트 시프트가 실제로 더 효율적인지 확인하기 위해 .NET에서 성능 테스트를 수행 했습니까? 얼마 전 xor-swap의 상태를 살펴본 결과 .NET에서 temp 변수를 사용하는 것보다 실제로 느리다는 것을 알았습니다.
Pete

7

Windows 탐색기의 상세보기에 표시된 크기와 일치시키려는 경우 원하는 코드입니다.

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

이것은 탐색기와 정확하게 일치 할뿐만 아니라 번역 된 문자열을 제공하고 Windows 버전 (예 : Win10, K = 1000과 이전 버전 K = 1024)의 차이점과도 일치합니다.


이 코드는 컴파일되지 않으므로 함수의 출처 인 dll을 지정해야합니다. 전체 함수 프로토 타입은 다음과 같습니다 : [DllImport ( "shlwapi.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern long StrFormatKBSize (long qdw, [MarshalAs (UnmanagedType.LPTStr)]] StringBuilder pszBuf, int cchBuf ); 이 솔루션을 선호하는 사람은 내가 먼저하겠습니다. 휠이 이미 발명 된 경우 왜 휠을 다시 발명해야합니까? 이것은 모든 C # 프로그래머의 일반적인 접근 방식이지만 불행히도 C #은 C ++에 도달하는 모든 대상에 도달하지 않습니다.
TarmoPikaro

그리고 버그 수정 : Int64.MaxValue는 9,223,372,036,854,775,807에 도달하며 25 +의 버퍼 크기를 할당해야합니다-위의 데모 코드와 같이 11이 아닌 경우를 대비하여 32로 반올림했습니다.
TarmoPikaro

감사합니다 @TarmoPikaro. 작업 코드에서 복사했을 때 DllImport를 놓쳤습니다. 또한 권장 사항에 따라 버퍼 크기를 늘 렸습니다. 잘 잡아!
Metalogic

인상적인 접근
tbhaxor

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
}


3

@ NET3의 솔루션처럼. bytes나누기는 CPU 비용이 더 많이 들기 때문에 나누기 대신 shift를 사용하여 범위를 테스트하십시오 .

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

재귀는 어떻습니까?

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

좋은하지만 CPU를 먹는다
kamalpreet

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입니다. 문화를 기반으로 전환하는 코드가 잘못된 정보를 생성하고 있습니다.
Superbest

1

그만한 가치가있는 또 하나의 접근법. 위에서 언급 한 @humbads 최적화 솔루션을 좋아했기 때문에 원칙을 복사했지만 조금 다르게 구현했습니다.

확장 방법이어야하는지에 대해 논쟁의 여지가 있다고 가정하지만 (모든 long이 반드시 바이트 크기는 아니기 때문에) 그것들을 좋아하며 다음에 필요할 때 메소드를 찾을 수있는 곳입니다!

단위에 관해서는, 나는 내 인생에서 '키비 바이트'나 '메비 바이트'라고 말한 적이 없다고 생각하며, 진화 된 표준보다는 강제로 그러한 표준에 회의적이지만 장기적으로 혼란을 피할 것이라고 생각합니다. .

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

아래 의 Long 확장 방법을 사용하여 사람이 읽을 수있는 크기 문자열로 변환합니다. 이 방법은 스택 오버플로에 게시 된이 같은 질문의 자바 솔루션의 C #을 구현 여기 .

/// <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";
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.