program story

.NET은 바이트를 KB, MB, GB 등으로 쉽게 변환하는 방법을 제공합니까?

inputbox 2020. 8. 29. 11:01
반응형

.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) 
    // [i.e. 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;

또한 문자열 표현 및 구문 분석을 수행합니다.

// 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 변형 추가 ... 그리고 copypasta 오타 수정 ...

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

가장 많이 득표 한 답변의 짧은 버전에는 TB 값에 문제가 있습니다.

tb 값도 처리하고 루프 없이도 적절하게 조정하고 음수 값에 대해 약간의 오류 검사를 추가했습니다. 내 해결책은 다음과 같습니다.

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

아니요. 대부분 틈새 시장이 필요하고 가능한 변형이 너무 많기 때문입니다. ( "KB", "Kb"또는 "Ko"입니까? 메가 바이트 1024 * 1024 바이트 또는 1024 * 1000 바이트입니까?-예, 일부 장소에서 사용합니다!)


다음은 확장하기 쉬운 옵션이지만 라이브러리 자체에 내장 된 옵션은 없습니다.

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)


NeverHopeless의 우아한 솔루션을 기반으로 :

private static readonly KeyValuePair<long, string>[] Thresholds = 
{
    // new KeyValuePair<long, string>(0, " Bytes"), // Don't devide by Zero!
    new KeyValuePair<long, string>(1, " Byte"),
    new KeyValuePair<long, string>(2, " Bytes"),
    new KeyValuePair<long, string>(1024, " KB"),
    new KeyValuePair<long, string>(1048576, " MB"), // Note: 1024 ^ 2 = 1026 (xor operator)
    new KeyValuePair<long, string>(1073741824, " GB"),
    new KeyValuePair<long, string>(1099511627776, " TB"),
    new KeyValuePair<long, string>(1125899906842620, " PB"),
    new KeyValuePair<long, string>(1152921504606850000, " EB"),

    // These don't fit into a int64
    // new KeyValuePair<long, string>(1180591620717410000000, " ZB"), 
    // new KeyValuePair<long, string>(1208925819614630000000000, " YB") 
};

/// <summary>
/// Returns x Bytes, kB, Mb, etc... 
/// </summary>
public static string ToByteSize(this long value)
{
    if (value == 0) return "0 Bytes"; // zero is plural
    for (int t = Thresholds.Length - 1; t > 0; t--)
        if (value >= Thresholds[t].Key) return ((double)value / Thresholds[t].Key).ToString("0.00") + Thresholds[t].Value;
    return "-" + ToByteSize(-value); // negative bytes (common case optimised to the end of this routine)
}

댓글이 너무 많을 수도 있지만, 앞으로 방문 할 때 같은 실수를하지 않도록 남겨 두는 편입니다.


@Servy의 대답 은 훌륭하고 간결했습니다. 더 간단할까요?

private static string[] suffixes = new [] { " B", " KB", " MB", " GB", " TB", " PB" };

public static string ToSize(double number, int precision = 2)
{
    // unit's number of bytes
    const double unit = 1024;
    // suffix counter
    int i = 0;
    // as long as we're bigger than a unit, keep going
    while(number > unit)
    {
        number /= unit;
        i++;
    }
    // apply precision and current suffix
    return Math.Round(number, precision) + suffixes[i];
}

아니.

하지만 이렇게 구현할 수 있습니다.

    static double ConvertBytesToMegabytes(long bytes)
    {
    return (bytes / 1024f) / 1024f;
    }

    static double ConvertKilobytesToMegabytes(long kilobytes)
    {
    return kilobytes / 1024f;
    }

또한 바이트 단위의 파일 크기를 메가 또는 기가 바이트로 올바르게 변환하는 방법을 확인하십시오 .


여기에 대한 답변 중 일부를 훌륭하게 작동하는 두 가지 방법으로 결합했습니다. 아래의 두 번째 방법은 바이트 문자열 (예 : 1.5.1GB)에서 다시 바이트 (예 : 1621350140)를 long 유형 값으로 변환합니다. 나는 이것이 바이트를 문자열로 변환하고 다시 바이트로 변환하는 솔루션을 찾는 다른 사람들에게 유용하기를 바랍니다.

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"

나는 JerKimballs 솔루션으로 갔고 그것에 좋아요. 그러나 나는 이것이 실제로 전체적으로 논란의 문제라는 점을 덧붙이거나 지적하고 싶다. 내 연구에서 (다른 이유로) 다음 정보를 얻었습니다.

평범한 사람들 (나는 그들이 존재한다고 들었습니다)이 기가 바이트에 대해 말할 때, 그들은 1000의 원래 바이트 수 == 기가 바이트 수에서 3의 거듭 제곱 인 미터법을 말합니다. 그러나 물론 위키피디아에 잘 요약 된 IEC / JEDEC 표준이 있는데, 1000 대신 x의 거듭 제곱이 1024입니다. 물리적 저장 장치의 경우 (아마존과 같은 논리적이라고 생각합니다) 미터법과 IEC 간의 차이가 계속 증가하고 있습니다. 예를 들어 1TB == 1 테라 바이트 메트릭은 1000의 4 제곱이지만 IEC는 공식적으로 유사한 숫자를 1TiB, 테비 바이트는 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);
    }
}

재귀는 어떻습니까?

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

위에 게시 된 바와 같이 재귀는 로그의 도움으로 가장 선호되는 방법입니다.

다음 함수에는 3 개의 인수가 있습니다. 입력, 출력의 차원 제약 조건, 즉 세 번째 인수입니다.

int ByteReDim(unsigned long ival, int constraint, unsigned long *oval)
{
    int base = 1 + (int) log10(ival);

    (*oval) = ival;
    if (base > constraint) {
        (*oval) = (*oval) >> 10;
        return(1 + ByteReDim((*oval), constraint, oval));
    } else
        return(0);
}

이제 12GB RAM을 여러 단위로 변환 해 보겠습니다.

int main(void)
{
    unsigned long RAM;
    int unit; // index of below symbols array
    char symbol[5] = {'B', 'K', 'M', 'G', 'T'};

    unit = ByteReDim(12884901888, 12, &RAM);
    printf("%lu%c\n", RAM, symbol[unit]); // output is 12884901888B

    unit = ByteReDim(12884901888, 9, &RAM);
    printf("%lu%c\n", RAM, symbol[unit]); // output is 12582912K

    unit = ByteReDim(12884901888, 6, &RAM);
    printf("%lu%c\n", RAM, symbol[unit]); // output is 12288M

    unit = ByteReDim(12884901888, 3, &RAM);
    printf("%lu%c\n", RAM, symbol[unit]); // output is 12G
}

나는 이것을 Windows (이진 접두사)에 사용합니다.

static readonly string[] BinaryPrefix = { "bytes", "KB", "MB", "GB", "TB" }; // , "PB", "EB", "ZB", "YB"
string GetMemoryString(double bytes)
{
    int counter = 0;
    double value = bytes;
    string text = "";
    do
    {
        text = value.ToString("0.0") + " " + BinaryPrefix[counter];
        value /= 1024;
        counter++;
    }
    while (Math.Floor(value) > 0 && counter < BinaryPrefix.Length);
    return text;
}

참고 URL : https://stackoverflow.com/questions/14488796/does-net-provide-an-easy-way-convert-bytes-to-kb-mb-gb-etc

반응형