Thursday 19 July 2012

Displaying File Sizes

Readability by Approximation

When it comes to displaying "rough" file sizes (1.2 KB, 34.5 MB, etc), and none of the online solutions offer exactly what you want, then you write your own struct:
public struct ByteCount
{
 public long Value { get; set; }

 public ByteCount(long value) : this() { Value = value; }

 public static ByteCount operator + (ByteCount x) { return x; }
 public static ByteCount operator - (ByteCount x) { return new ByteCount(-x.Value); }

 public static ByteCount operator + (ByteCount x, ByteCount y) { return x + y.Value; }
 public static ByteCount operator + (ByteCount x, long y) { return new ByteCount(x.Value + y); }
 public static ByteCount operator + (long x, ByteCount y) { return y + x; }

 public static ByteCount operator - (ByteCount x, ByteCount y) { return x + -y; }
 public static ByteCount operator - (ByteCount x, long y) { return x + -y; }
 public static ByteCount operator - (long x, ByteCount y) { return x + -y; }

 public override string ToString()
 {
  const string units = "EPTGMK";
  var unitSize = 1L << 10 * units.Length;
  foreach (var unit in units)
  {
   if (Value >= unitSize)
   {
    var value = decimal.Divide(Value, unitSize);
    return string.Format(
     string.Format(
      "{{0:{0}}} {{1}}B",
      value >= 100 ? "#" : value >= 10 ? "#.#" : "#.##"),
     value, unit);
   }
   unitSize >>= 10;
  }
  return string.Format("{0} Bytes", Value);
 }
}
This outputs a consistent three significant figures, with the exception of cases 1000..1023 Bytes, which are output as-is. The supplied set of overloaded operators sufficed for the immediate requirements of my app, which involved only accumulating and subtracting totals, but can obviously be extended easily to include comparisons, multiplication, implicit conversions, etc. Notice the nested calls to string.Format() using escaped {{i.e., doubled-up}} braces, as previously illustrated under C# String Format Run Time Field Width.

No comments:

Post a Comment