在 C# 中将字节转换为 GB?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1242266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:06:41  来源:igfitidea点击:

Converting bytes to GB in C#?

c#refactoring

提问by Michael Kniskern

I was refactoring some old code and came across the following line of code to convert bytes to GB.

我正在重构一些旧代码并遇到以下代码行将字节转换为 GB。

decimal GB = KB / 1024 / 1024 / 1024;

Is there a better way to refactor the following piece of code?

有没有更好的方法来重构以下代码?

Update

更新

I meant to say bytes to Gigabytes. I gave wrong information.

我的意思是说字节到千兆字节。我提供了错误的信息。

回答by Rex M

If exact precision is not important, use double:

如果精确精度不重要,请使用 double:

double gb = kb / 1048576D

Agree with Pavel here - there's not really any need to refactor this code... in fact, if this is the biggest problem in your codebase, I think you might be sitting on the most well-written software ever.

同意 Pavel 的观点——实际上没有任何必要重构这段代码……事实上,如果这是你代码库中最大的问题,我认为你可能会坐在有史以来编写得最好的软件上。

回答by mattnewport

Personally I'd write it like this: decimal GB = KB / (1024 * 1024);but there's really no need to refactor the code as written.

就我个人而言,我会这样写:decimal GB = KB / (1024 * 1024);但实际上没有必要按照编写的方式重构代码。

回答by technophile

The original code is succinct, easy to read, and with reasonable variable names, self-documenting; I wouldn't change it.

原代码简洁易读,变量名合理,自文档化;我不会改变它。

If you absolutely must refactor, you could create a set of extension methods on the numeric types:

如果你绝对必须重构,你可以在数字类型上创建一组扩展方法:

public static double BytesToKilobytes(this Int32 bytes)
{
    return bytes / 1024d;
}
public static double BytesToMegabytes(this Int32 bytes)
{
    return bytes / 1024d / 1024d;
}
public static double KilobytesToBytes(this double kilobytes)
{
    return kilobytes * 1024d;
}

//You can then do something like:
double filesize = 32.5d;
double bytes = filesize.KilobytesToBytes();

But unless your code does virtually nothing but convert bytes to kilobytes etc, all this will really do is clutter up Intellisense for no real gain.

但是,除非您的代码除了将字节转换为千字节等之外几乎什么都不做,否则所有这些实际上只会使 Intellisense 变得混乱而没有真正的收益。

回答by paxdiablo

Well, the formula is wrong (there's only about a million kilobytes in a gigabyte, not a thousand million) but, other than that, it's fine. Anyone used to working with these numbers will know what it means.

嗯,这个公式是错误的(一千兆字节只有大约一百万千字节,而不是一亿),但除此之外,还可以。任何习惯使用这些数字的人都会知道它的含义。

One thing I would watch out for (and I don't know if this is a problem with C#) is that a compiler may not be able to optimize the x/1024/1024if xis not a basic type. With C and integers, the compiler would quite easily turn that into a "blindingly-fast-shift-right-by-20-bits" instruction.

我要注意的一件事(我不知道这是否是 C# 的问题)是编译器可能无法优化x/1024/1024ifx不是基本类型。使用 C 和整数,编译器很容易将其转换为“盲目快速右移 20 位”指令。

If decimal is a class rather than a basic type, the compiler may have to do two divide operations. Whether this has any real impact on speed (or even whether it happens at all) is outside of my sphere of knowledge.

如果decimal 是一个类而不是一个基本类型,编译器可能需要做两个除法运算。这是否对速度有任何真正的影响(甚至它是否发生)超出了我的知识范围。

One thing I'd consider changing is the actual variable names. It makes no real difference to the compiled code but I prefer longer variable names rather than abbreviations, so I'd opt for kiloBytes/gigaBytesor something like that. KB/GBis too easy to get confused with constants, depending on your coding standards.

我会考虑更改的一件事是实际的变量名称。它对编译后的代码没有真正的影响,但我更喜欢更长的变量名而不是缩写,所以我会选择kiloBytes/gigaBytes或类似的东西。KB/GB太容易与常量混淆,这取决于您的编码标准。

回答by Guffa

To make sure that the compiler pre-calculates the divisors:

要确保编译器预先计算除数:

decimal GB = KB / (1024 * 1024);

Note that you are actually calculating GiB (gibibyte), not GB (gigabyte). If you really want to calculate GB, that would be:

请注意,您实际上是在计算 GiB(千兆字节),而不是 GB(千兆字节)。如果你真的想计算 GB,那就是:

decimal GB = KB / (1000 * 1000);

回答by Kenan E. K.

In theory, this is faster (precomputing the constant to do multiplication instead of division). It's probably not used often enough to matter, but just in case.

理论上,这更快(预先计算常量以进行乘法而不是除法)。它的使用频率可能不够高,但以防万一。

double const KbToGbFactor = 1d / 1024 /1024;

double gb = kb * KbToGbFactor;

回答by JLopez

I developed this method here, works up to TB.

我在这里开发了这种方法,适用于 TB。

private static string FormatBytes(long bytes)
{
    string[] Suffix = { "B", "KB", "MB", "GB", "TB" };
    int i;
    double dblSByte = bytes;
    for (i = 0; i < Suffix.Length && bytes >= 1024; i++, bytes /= 1024) 
    {
        dblSByte = bytes / 1024.0;
    }

    return String.Format("{0:0.##} {1}", dblSByte, Suffix[i]);
}

回答by AZ_

    /// <summary>
/// Function to convert the given bytes to either Kilobyte, Megabyte, or Gigabyte
/// </summary>
/// <param name="bytes">Double -> Total bytes to be converted</param>
/// <param name="type">String -> Type of conversion to perform</param>
/// <returns>Int32 -> Converted bytes</returns>
/// <remarks></remarks>
public static double ConvertSize(double bytes, string type)
{
    try
    {
        const int CONVERSION_VALUE = 1024;
        //determine what conversion they want
        switch (type)
        {
            case "BY":
                 //convert to bytes (default)
                 return bytes;
            case "KB":
                 //convert to kilobytes
                 return (bytes / CONVERSION_VALUE);
            case "MB":
                 //convert to megabytes
                 return (bytes / CalculateSquare(CONVERSION_VALUE));
            case "GB":
                 //convert to gigabytes
                 return (bytes / CalculateCube(CONVERSION_VALUE));
            default:
                 //default
                 return bytes;
          }
     }
     catch (Exception ex)
     {
         Console.WriteLine(ex.Message);
         return 0;
      }
}

/// <summary>
/// Function to calculate the square of the provided number
/// </summary>
/// <param name="number">Int32 -> Number to be squared</param>
/// <returns>Double -> THe provided number squared</returns>
/// <remarks></remarks>
public static double CalculateSquare(Int32 number)
{
     return Math.Pow(number, 2);
}


/// <summary>
/// Function to calculate the cube of the provided number
/// </summary>
/// <param name="number">Int32 -> Number to be cubed</param>
/// <returns>Double -> THe provided number cubed</returns>
/// <remarks></remarks>
public static double CalculateCube(Int32 number)
{
     return Math.Pow(number, 3);
}

//Sample Useage
String Size = "File is " + ConvertSize(250222,"MB") + " Megabytes in size"

回答by EladTal

I needed it the other way around, convert from 3rd party component literal size in words (e.g. "0 bytes", "1.1 MB") into generic size in bytes. so I used it this way:

我需要反过来,从 3rd 方组件文字大小(例如“0 字节”、“1.1 MB”)转换为通用大小(以字节为单位)。所以我这样使用它:

        private static long UnformatBytes(string sizeInWords)
    {
        if(string.IsNullOrWhiteSpace(sizeInWords))
            return -1;

        string size = sizeInWords.Split(' ').FirstOrDefault();
        double result;
        if (string.IsNullOrWhiteSpace(size) || !double.TryParse(size, out result))
        {
            Debugger.Break();
            return -1;
        }

        int pow;

        if (sizeInWords.IndexOf("byte", StringComparison.OrdinalIgnoreCase) > -1)
            pow = 0;
        else if (sizeInWords.IndexOf("kb", StringComparison.OrdinalIgnoreCase) > -1)
            pow = 1;
        else if (sizeInWords.IndexOf("mb", StringComparison.OrdinalIgnoreCase) > -1)
            pow = 2;
        else if (sizeInWords.IndexOf("gb", StringComparison.OrdinalIgnoreCase) > -1)
            pow = 3;
        else if (sizeInWords.IndexOf("tb", StringComparison.OrdinalIgnoreCase) > -1)
            pow = 4;
        else
            return -1;

        return System.Convert.ToInt64((result * Math.Pow(1024, pow)));
    }

回答by JGU

I wrote a small utility class that performs conversions between units, hth..

我编写了一个小型实用程序类,用于执行单位之间的转换,hth ..

#region StorageDifferential
/// <summary>
/// Converts between Base 2 or Base 10 storage units [TB, GB, MB, KB, Bytes]
/// </summary>
public enum Differential : int
{
    /// <summary>
    /// Convert Bytes to Kilobytes
    /// </summary>
    ByteToKilo,
    /// <summary>
    /// Convert Bytes to Megabytes
    /// </summary>
    ByteToMega,
    /// <summary>
    /// Convert Bytes to Gigabytes
    /// </summary>
    ByteToGiga,
    /// <summary>
    /// Convert Bytes to Teraytes
    /// </summary>
    ByteToTera,
    /// <summary>
    /// Convert Kilobytes to Bytes
    /// </summary>
    KiloToByte,
    /// <summary>
    /// Convert Kilobytes to Megabytes
    /// </summary>
    KiloToMega,
    /// <summary>
    /// Convert Kilobytes to Gigabytes
    /// </summary>
    KiloToGiga,
    /// <summary>
    /// Convert Kilobytes to Terabytes
    /// </summary>
    KiloToTera,
    /// <summary>
    /// Convert Megabytes to Bytes
    /// </summary>
    MegaToByte,
    /// <summary>
    /// Convert Megabytes to Kilobytes
    /// </summary>
    MegaToKilo,
    /// <summary>
    /// Convert Megabytes to Gigabytes
    /// </summary>
    MegaToGiga,
    /// <summary>
    /// Convert Megabytes to Terabytes
    /// </summary>
    MegaToTera,
    /// <summary>
    /// Convert Gigabytes to Bytes
    /// </summary>
    GigaToByte,
    /// <summary>
    /// Convert Gigabytes to Kilobytes
    /// </summary>
    GigaToKilo,
    /// <summary>
    /// Convert Gigabytes to Megabytes
    /// </summary>
    GigaToMega,
    /// <summary>
    /// Convert Gigabytes to Terabytes
    /// </summary>
    GigaToTerra,
    /// <summary>
    /// Convert Terabyte to Bytes
    /// </summary>
    TeraToByte,
    /// <summary>
    /// Convert Terabyte to Kilobytes
    /// </summary>
    TeraToKilo,
    /// <summary>
    /// Convert Terabytes to Megabytes
    /// </summary>
    TeraToMega,
    /// <summary>
    /// Convert Terabytes to Gigabytes
    /// </summary>
    TeraToGiga,
}
#endregion

#region Storage Sizes
/// <summary>
/// Enumeration of recognized storage sizes [in Bytes]
/// </summary>
public enum StorageSizes : long
{
    /// <summary>
    /// Base 10 Conversion
    /// </summary>
    KILOBYTE = 1000,
    MEGABYTE = 1000000,
    GIGABYTE = 1000000000,
    TERABYTE = 1000000000000,
    /// <summary>
    /// Base 2 Conversion
    /// </summary>
    KIBIBYTE = 1024,
    MEBIBYTE = 1048576,
    GIBIBYTE = 1073741824,
    TEBIBYTE = 1099511627776,
}
#endregion

#region StorageBase
/// <summary>
/// Storage powers 10 based or 1024 based
/// </summary>
public enum StorageBase : int
{
    /// <summary>
    /// 1024 Base power, Typically used in memory measurements
    /// </summary>
    BASE2,
    /// <summary>
    /// 10 Base power, Used in storage mediums like harddrives
    /// </summary>
    BASE10,
}
#endregion

/// <summary>
/// Convert between base 1024 storage units [TB, GB, MB, KB, Byte]
/// </summary>
public static class StorageConverter
{
    /// <summary>
    /// Convert between base 1024 storage units [TB, GB, MB, KB, Byte]
    /// </summary>
    /// <param name="SizeDifferential">Storage conversion differential [enum]</param>
    /// <param name="UnitSize">Size as mutiple of unit type units [double]</param>
    /// <param name="BaseUnit">Size of the base power [enum]</param>
    /// <returns>Converted unit size [double]</returns>
    public static double Convert(Differential SizeDifferential, double UnitSize, StorageBase BaseUnit = StorageBase.BASE10)
    {
        if (UnitSize < 0.000000000001) return 0;

        double POWER1 = 1000;
        double POWER2 = 1000000;
        double POWER3 = 1000000000;
        double POWER4 = 1000000000000;

        if (BaseUnit == StorageBase.BASE2)
        {
            POWER1 = 1024;
            POWER2 = 1048576;
            POWER3 = 1073741824;
            POWER4 = 1099511627776;
        }

        switch (SizeDifferential)
        {
            case Differential.ByteToKilo:
                return UnitSize / POWER1;
            case Differential.ByteToMega:
                return UnitSize / POWER2;
            case Differential.ByteToGiga:
                return UnitSize / POWER3;
            case Differential.ByteToTera:
                return UnitSize / POWER4;
            case Differential.KiloToByte:
                return UnitSize * POWER1;
            case Differential.KiloToMega:
                return UnitSize / POWER1;
            case Differential.KiloToGiga:
                return UnitSize / POWER2;
            case Differential.KiloToTera:
                return UnitSize / POWER3;
            case Differential.MegaToByte:
                return UnitSize * POWER2;
            case Differential.MegaToKilo:
                return UnitSize * POWER1;
            case Differential.MegaToGiga:
                return UnitSize / POWER1;
            case Differential.MegaToTera:
                return UnitSize / POWER2;
            case Differential.GigaToByte:
                return UnitSize * POWER3;
            case Differential.GigaToKilo:
                return UnitSize * POWER2;
            case Differential.GigaToMega:
                return UnitSize * POWER1;
            case Differential.GigaToTerra:
                return UnitSize / POWER1;
            case Differential.TeraToByte:
                return UnitSize * POWER4;
            case Differential.TeraToKilo:
                return UnitSize * POWER3;
            case Differential.TeraToMega:
                return UnitSize * POWER2;
            case Differential.TeraToGiga:
                return UnitSize * POWER1;
        }

        return 0;
    }
}