我如何获得一个人类可读的文件大小字节缩写使用。net ?

例子: 输入7,326,629,显示6.98 MB


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

我猜你要找的是“1.4 MB”而不是“1468006字节”?

我不认为在。net中有内置的方法来做到这一点。你只需要找出哪个单元是合适的,然后格式化它。

编辑:这里有一些示例代码来做到这一点:

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


这可能不是最有效或最优化的方法,但如果您不熟悉对数数学,它更容易阅读,并且对于大多数情况来说应该足够快。

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

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

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

使用日志解决问题....

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

编辑: 有人指出我漏了一门数学课。地板,所以我把它合并了。(转换。ToInt32使用舍入,而不是截断,这就是为什么需要使用Floor。)谢谢你的帮助。

Edit2: 有一些关于负大小和0字节大小的注释,所以我更新以处理这些情况。


所有溶液的混合:-)

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

请求函数的测试和显著优化版本发布在这里:

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

我的观点是:

千字节的前缀是kB(小写K) 由于这些函数用于表示目的,因此应该提供区域性,例如:CurrentCulture,“{0时。##}{1}",文件大小,单位); 根据上下文,千字节可以是1000字节或1024字节。MB、GB等也是如此。


又多了一种方法,不管怎样。我喜欢上面提到的@humbads优化解决方案,所以复制了原理,但我实现了一点不同。

我认为它是否应该是一个扩展方法是有争议的(因为不是所有的long都必须是字节大小),但我喜欢它们,当我下次需要它时,我可以在某个地方找到它!

关于单位,我想我从来没有说过“Kibibyte”或“Mebibyte”,虽然我对这种强制而非进化的标准持怀疑态度,但我认为从长远来看,这将避免混淆。

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

检查我的ByteSize库。这是系统的问题。TimeSpan for bytes!

它为您处理转换和格式化。

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

有一个开源项目可以做到这一点,甚至更多。

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


我喜欢使用以下方法(它支持高达tb,这在大多数情况下已经足够了,但它可以很容易地扩展):

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)编写的,因此对于较早的版本可能需要进行一些编辑。


如果你试图匹配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 vs.之前的版本K = 1024)。


比如@NET3的解决方案。使用shift而不是除法来测试字节的范围,因为除法占用更多的CPU成本。

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

那么递归呢:

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

下面是一个自动确定单位的简明答案。

public static string ToBytesCount(this long bytes)
{
    int unit = 1024;
    string unitStr = "B";
    if (bytes < unit)
    {
        return string.Format("{0} {1}", bytes, 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);
}

“b”代表bit,“b”代表Byte,“KMGTPEZY”分别代表kilo, mega, giga, tera, peta, exa, zetta和yotta

可以将ISO/IEC80000纳入考虑范围:

public static string ToBytesCount(this long bytes, bool isISO = true)
{
    int unit = isISO ? 1024 : 1000;
    string unitStr = "B";
    if (bytes < unit)
    {
        return string.Format("{0} {1}", bytes, unitStr);
    }
    int exp = (int)(Math.Log(bytes) / Math.Log(unit));
    return string.Format("{0:##.##} {1}{2}{3}", bytes / Math.Pow(unit, exp), "KMGTPEZY"[exp - 1], isISO ? "i" : "", unitStr);
}

我使用下面的Long扩展方法将其转换为人类可读的大小字符串。这个方法是在Stack Overflow上发布的相同问题的Java解决方案的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";
}

下面是一个Log10的方法:

using System;

class Program {
   static string NumberFormat(double n) {
      var n2 = (int)Math.Log10(n) / 3;
      var n3 = n / Math.Pow(1e3, n2);
      return String.Format("{0:f3}", n3) + new[]{"", " k", " M", " G"}[n2];
   }

   static void Main() {
      var s = NumberFormat(9012345678);
      Console.WriteLine(s == "9.012 G");
   }
}

https://learn.microsoft.com/dotnet/api/system.math.log10


为了获得人类可读的字符串,就像用户在Windows环境中习惯的那样,你应该使用StrFormatByteSize():

using System.Runtime.InteropServices;

...

private long mFileSize;

[DllImport("Shlwapi.dll", CharSet = CharSet.Auto)]
public static extern int StrFormatByteSize(
    long fileSize,
    [MarshalAs(UnmanagedType.LPTStr)] StringBuilder buffer,
    int bufferSize);
    
public string HumanReadableFileSize
{
    get
    {
        var sb = new StringBuilder(20);
        StrFormatByteSize(mFileSize, sb, 20);
        return sb.ToString();
    }
}

我在这里找到了这个: http://csharphelper.com/blog/2014/07/format-file-sizes-in-kb-mb-gb-and-so-forth-in-c/


下面是@ deepe1的BigInteger版本的答案,它绕过了long的大小限制(因此支持yottabyte和理论上的任何后面的限制):

public static string ToBytesString(this BigInteger byteCount, string format = "N3")
{
    string[] suf = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "YiB" };
    if (byteCount.IsZero)
    {
        return $"{0.0.ToString(format)} {suf[0]}";
    }

    var abs = BigInteger.Abs(byteCount);
    var place = Convert.ToInt32(Math.Floor(BigInteger.Log(abs, 1024)));
    var pow = Math.Pow(1024, place);

    // since we need to do this with integer math, get the quotient and remainder
    var quotient = BigInteger.DivRem(abs, new BigInteger(pow), out var remainder);
    // convert the remainder to a ratio and add both back together as doubles
    var num = byteCount.Sign * (Math.Floor((double)quotient) + ((double)remainder / pow));

    return $"{num.ToString(format)} {suf[place]}";
}

1-liner(加上前缀常量)

const String prefixes = " KMGTPEY";
/// <summary> Returns the human-readable file size for an arbitrary, 64-bit file size. </summary>
public static String HumanSize(UInt64 bytes)
    => Enumerable
    .Range(0, prefixes.Length)
    .Where(i => bytes < 1024U<<(i*10))
    .Select(i => $"{(bytes>>(10*i-10))/1024:0.###} {prefixes[i]}B")
    .First();

或者,如果你想减少LINQ对象的分配,使用相同的for循环变量:

/// <summary>
/// Returns the human-readable file size for an arbitrary, 64-bit file size.
/// </summary>
public static String HumanSize(UInt64 bytes)
{
    const String prefixes = " KMGTPEY";
    for (var i = 0; i < prefixes.Length; i++)
        if (bytes < 1024U<<(i*10))
            return $"{(bytes>>(10*i-10))/1024:0.###} {prefixes[i]}B";

    throw new ArgumentOutOfRangeException(nameof(bytes));
}

这个问题很老了,但是一个非常快速的c#函数可以是:

public static string PrettyPrintBytes(long numBytes)
{
    if (numBytes < 1024)
        return $"{numBytes} B";
            
    if (numBytes < 1048576)
        return $"{numBytes / 1024d:0.##} KB";

    if (numBytes < 1073741824)
        return $"{numBytes / 1048576d:0.##} MB";

    if (numBytes < 1099511627776)
        return $"{numBytes / 1073741824d:0.##} GB";

    if (numBytes < 1125899906842624)
        return $"{numBytes / 1099511627776d:0.##} TB";
            
    if (numBytes < 1152921504606846976)
        return $"{numBytes / 1125899906842624d:0.##} PB";

    return $"{numBytes / 1152921504606846976d:0.##} EB";
}

每次调用只有一次强制转换和一次除法,最多只能进行6次比较。在进行基准测试时,我发现字符串插值比使用string . format()快得多。


这里没有什么东西完全符合我的需要,我根据这个线程制作了我自己的,所以这里是我的长扩展,允许您根据标准选择格式要求。

绝对不是最快的,但很灵活。支持EB/EiB。

// <summary>
/// <paramref name="byteCount"/> The original size in bytes ( 8 bits )
/// <paramref name="notationFormat"/> is supported in the following ways:
/// [    'B' / 'b' : Binary :   Kilobyte (KB) is 1024 bytes, Megabyte (MB) is 1048576 bytes, etc    ]
/// [    'I' / 'i' : IEC:       Kibibyte (KiB) is 1024 bytes, Mebibyte (MiB) is 1048576 bytes, etc    ]
/// [    'D' / 'd' : Decimal :  Kilobyte (KB) is 1000 bytes, Megabyte (MB) is 1000000 bytes, etc    ]
/// </summary>

public static string ToDataSizeString( this long byteCount, char notationFormat = 'b' )
{
    char[] supportedFormatChars = { 'b', 'i', 'd' };

    var lowerCaseNotationFormat = char.ToLowerInvariant( notationFormat );

    // Stop shooting holes in my ship!
    if ( !supportedFormatChars.Contains( lowerCaseNotationFormat ) )
    {
        throw new ArgumentException( $"notationFormat argument '{notationFormat}' not supported" );
    }

    long ebLimit = 1152921504606846976;
    long pbLimit = 1125899906842624;
    long tbLimit = 1099511627776;
    long gbLimit = 1073741824;
    long mbLimit = 1048576;
    long kbLimit = 1024;

    var ebSuffix = "EB";
    var pbSuffix = "PB";
    var tbSuffix = "TB";
    var gbSuffix = "GB";
    var mbSuffix = "MB";
    var kbSuffix = "KB";
    var bSuffix  = " B";

    switch ( lowerCaseNotationFormat )
    {
        case 'b':
            // Sweet as
            break;

        case 'i':
            // Limits stay the same, suffixes need changed
            ebSuffix = "EiB";
            pbSuffix = "PiB";
            tbSuffix = "TiB";
            gbSuffix = "GiB";
            mbSuffix = "MiB";
            kbSuffix = "KiB";
            bSuffix  = "  B";
            break;

        case 'd':
            // Suffixes stay the same, limits need changed
            ebLimit = 1000000000000000000;
            pbLimit = 1000000000000000;
            tbLimit = 1000000000000;
            gbLimit = 1000000000;
            mbLimit = 1000000;
            kbLimit = 1000;
            break;

        default:
            // Should have already Excepted, but hey whatever
            throw new ArgumentException( $"notationFormat argument '{notationFormat}' not supported" );

    }

    string fileSizeText;

    // Exa/Exbi sized
    if ( byteCount >= ebLimit )
    {
        fileSizeText = $"{( (double)byteCount / ebLimit ):N1} {ebSuffix}";
    }
    // Peta/Pebi sized
    else if ( byteCount >= pbLimit )
    {
        fileSizeText = $"{( (double)byteCount / pbLimit ):N1} {pbSuffix}";
    }
    // Tera/Tebi sized
    else if ( byteCount >= tbLimit )
    {
        fileSizeText = $"{( (double)byteCount / tbLimit ):N1} {tbSuffix}";
    }
    // Giga/Gibi sized
    else if ( byteCount >= gbLimit )
    {
        fileSizeText = $"{( (double)byteCount / gbLimit ):N1} {gbSuffix}";
    }
    // Mega/Mibi sized
    else if ( byteCount >= mbLimit )
    {
        fileSizeText = $"{( (double)byteCount / mbLimit ):N1} {mbSuffix}";
    }
    // Kilo/Kibi sized
    else if ( byteCount >= kbLimit )
    {
        fileSizeText = $"{( (double)byteCount / kbLimit ):N1} {kbSuffix}";
    }
    // Byte sized
    else
    {
        fileSizeText = $"{byteCount} {bSuffix}";
    }

    return fileSizeText;
}

这是我编的,效果很好。

public string[] DetermineDigitalSize(string filename)
        {
            string[] result = new string[2];
            string[] sizes = { "B", "KB", "MB", "GB", "GB" };
            double len = new FileInfo(filename).Length;
             double adjustedSize = len;
            double testSize = 0;
            int order = 0;
            while (order< sizes.Length-1)
            {
                testSize = adjustedSize / 1024;
                if (testSize >= 1) { adjustedSize = testSize; order++; }
                else { break; }
            }
            result[0] = $"{adjustedSize:f2}";
            result[1] = sizes[order];
            return result;
        }