The NeoSmart Files

PrettySize: a .NET library for printing human-readable file sizes

Continuing our promise to open source parts of our libraries and applications where possible, we’ve just released PrettySize, a C# and .NET library for representing file sizes in a human-readable (pretty) format. PrettySize is available for free (MIT-licensed) on GitHub and via NuGet for those that are interested, and forks, contributions, and pull-requests are actively encouraged.1

One of the best benefits of open-sourcing code is that it requires you to take a critical eye to what your code does and how it’s structured. Haphazard code interspersed throughout a dozen different files is cleaned up and re-organized in a way that can only bring benefits all around, from performance to ease-of-use, security, and future maintenance.

In this example, PrettySize went from supporting just a single notation format (2.34 KiB, for example), to supporting output using both base 10 (kilobyte, megabyte, KB, MB) and base 2 (kibibyte, mebibyte, KiB, MiB) units, with support for both abbreviated and unabridged units in the output.

Additionally, open-sourcing PrettySize also brought some performance improvements to bear (although any honest appraisal of the situation would start and end with pointing out that any sort of human-readable formatting is almost always going to be part of a much slower path in the code, namely printing to screen or similar, to an extent that actually forming the human-readable strings in question is going to be of negligible overhead), as the code went from a sequence of if (...) else ... statements like this:

if (size < 1 * (1L << 10))
{
    return size + " bytes";
}
else if (size < 10 * (1L << 10))
{
    return (size / (1.0 * (1L << 10))).ToString("N2") + " KiB";
}
else if (size < 100 * (1L << 10))
{
    return (size / (1.0 * (1L << 10))).ToString("N1") + " KiB";
}
...

where conversions of larger file sizes would have to go through each successive test until the matching clause was found, to a binary search performed against a sorted array of match ranges.

While the .NET Framework has included a binary tree-based SortedDictionary since .NET 2.0, it unfortunately does not support “fuzzy” lookups (à la C++’s std::map) where the nearest match can be returned, and so manipulations would be required to incoming sizes before being able to match them against a pre-existing lookup table. On the other hand, Array.BinarySearch will return the (binary, two’s complement) of the closest (higher) match if no exact match was found, letting us create a sorted list of formatting rules for each range, and then find the nearest match to service incoming requests.

In addition to converting numeric file sizes to formatted strings for human-readable representation, PrettySize also includes constants that can be used to make expressing your own size-related calculations easier, with both base 2 and base 10 units (and their abbreviations) exposed.

Some random facts learned in the process:

Anyway, that’s all for now. Go ahead and grab PrettySize from NuGet or off of GitHub and make life easier on yourself and your end users’ eyes!

Download: PrettySize 2.1.0


  1. If anyone wants to try their hand at implementing IFormattable, consider this an open invitation. It’s not a functionality we ever needed, but some might find it useful. ↩︎