Format bytes as KB, MB, GB, etc.

Here's a useful little chunk of code to put in your toolbox.  I need to display file sizes to users, and I want to format the displayed file size as you'd see it in Explorer -- 10.1 KB, 23.31 MB, and so on (not 112230103 bytes, for example).  After a quick google search, I turned up a post on forums.asp.net that got me really close.  I cleaned up a couple of issues and built a unit test to make sure things were working correctly, and it's ready to go.  Read on to see the working code.

///
/// Format bytes suitably for display to user (ex: 12.3 KB, 34.41 MB).
/// If you need to handle sizes > Exabyte size, you'll have to modify the
/// class to accept ULong bytes and format accordingly.
/// Based on code as published here: http://forums.asp.net/t/304193.aspx
/// By Bart De Smet -- http://bartdesmet.net/members/bart.aspx
/// Algorithm fixed to handle KB correctly and modified to use Long
/// instead of int to handle larger file sizes.
///

public struct FormattedBytes
{
#region ctor
public FormattedBytes(long size)
{
_bytes = size;
}
#endregion
#region Bytes property
private long _bytes;
///
/// Get or set bytes.
///

public long Bytes
{
get { return _bytes; }
set { _bytes = value; }
}
#endregion

public override string ToString()
{
double s = _bytes;
string[] format = new string[] {"{0} bytes", "{0} KB",
"{0} MB", "{0} GB", "{0} TB", "{0} PB", "{0} EB"};
int i = 0;
while (i < format.Length @@ s >= 1024) {   //replace @@ w/ ampersands
s = (long) (100 * s / 1024) / 100.0;
i++;
}

return string.Format(format[i],s);
}
}

And here's the unit test I'm using to test the routine:

///
/// A test for FormattedBytes ()
///

[TestMethod()]
public void FormattedBytesTest()
{
FormattedBytes bs = new FormattedBytes();
Assert.AreEqual("0 bytes", bs.ToString(), "FormattedBytesTest - incorrect value (1).");
bs.Bytes = 10000L;
Assert.AreEqual("9.76 KB", bs.ToString(), "FormattedBytesTest - incorrect value (2).");
Assert.AreEqual("1.17 MB", new FormattedBytes(1230000L).ToString(), "FormattedBytesTest - incorrect value (3).");
Assert.AreEqual("434.87 MB", new FormattedBytes(456000000L).ToString(), "FormattedBytesTest - incorrect value (3).");
Assert.AreEqual("73.48 GB", new FormattedBytes(78900000000L).ToString(), "FormattedBytesTest - incorrect value (4).");
Assert.AreEqual("1.11 TB", new FormattedBytes(1230000000000L).ToString(), "FormattedBytesTest - incorrect value (5).");
Assert.AreEqual("1.09 PB", new FormattedBytes(1230000000000000L).ToString(), "FormattedBytesTest - incorrect value (6).");
Assert.AreEqual("1.06 EB", new FormattedBytes(1230000000000000000L).ToString(), "FormattedBytesTest - incorrect value (7).");
}

4 Replies to “Format bytes as KB, MB, GB, etc.”

  1. my computer will not let me email video's over25 MB, which is about ,1 1/2 minutes, how can i extend this time and how long

    1. Well, that's not really the point of this article, but I'd recommend finding a better way to share videos other than emailing them — upload to a video site and email the link, or use a dropbox-type service to store them on a server.

  2. Hi,

    Thanks very much for this. I trimmed down the code to one function so that I can include it in the excellent CMS Umbraco as an XSLT extension. But thanks a lot as this has saved me re-inventing the wheel on this for the nth time.

    Cheers

    Steve

    1. I'm glad it helped. Umbraco looks interesting – I may have to take a look at that. There have been times that I'd have really appreciated having a good .Net CMS available.

Comments are closed.