using System; namespace Vanara { /// /// A custom formatter for byte sizes (things like files, network bandwidth, etc.) that will automatically determine the best abbreviation. /// public class ByteSizeFormatter : Formatter { private static readonly string[] suffixes = { " B", " KB", " MB", " GB", " TB", " PB", " EB" }; /// A static instance of . public static readonly ByteSizeFormatter Instance = new ByteSizeFormatter(); /// /// Converts the value of a specified object to an equivalent string representation using specified format and culture-specific /// formatting information. /// /// A format string containing formatting specifications. /// An object to format. /// An object that supplies format information about the current instance. /// /// The string representation of the value of , formatted as specified by and /// . /// public override string Format(string format, object arg, IFormatProvider formatProvider) { long bytes; try { bytes = Convert.ToInt64(arg); } catch { return HandleOtherFormats(format, arg); } if (bytes == 0) return "0" + suffixes[0]; var m = System.Text.RegularExpressions.Regex.Match(format, @"^[B|b](?\d+)?$"); if (!m.Success) return HandleOtherFormats(format, arg); var prec = m.Groups["prec"].Success ? byte.Parse(m.Groups["prec"].Value) : 0; var place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); if (place >= suffixes.Length) place = suffixes.Length - 1; var num = Math.Round(bytes / Math.Pow(1024, place), 1); return $"{num.ToString("F" + prec).TrimEnd('0')}{suffixes[place]}"; } /// /// Converts the string representation of a byte size to its 64-bit signed integer equivalent. A return value indicates whether the /// conversion succeeded. /// /// A string containing a byte size to convert. /// /// When this method returns, contains the 64-bit signed integer value equivalent of the value contained in , /// if the conversion succeeded, or zero if the conversion failed. The conversion fails if the parameter is /// null or Empty, or is not of the correct format. This parameter is passed uninitialized; any value originally supplied in result /// will be overwritten. /// /// if was converted successfully; otherwise, . /// public static bool TryParse(string input, out long bytes) { const string expr = @"^\s*(?\d+(?:\.\d+)?)\s*(?[kKmMgGtTpPeEyY]?[bB])?\s*$"; var match = System.Text.RegularExpressions.Regex.Match(input, expr); bytes = 0; if (!match.Success) return false; long mult = 1; switch (match.Groups["mod"].Value.ToUpper()) { case "B": case "": break; case "KB": mult = 1024; break; case "MB": mult = (long)Math.Pow(1024, 2); break; case "GB": mult = (long)Math.Pow(1024, 3); break; case "TB": mult = (long)Math.Pow(1024, 4); break; case "PB": mult = (long)Math.Pow(1024, 5); break; case "EB": mult = (long)Math.Pow(1024, 6); break; case "YB": mult = (long)Math.Pow(1024, 7); break; default: throw new InvalidOperationException(); } bytes = (long)Math.Round(float.Parse(match.Groups["num"].Value) * mult); return true; } } }