BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Algorithms and Data Structures
.NET 1.1+

Vista-Style File Size Formatter

When copying files, Microsoft Windows Vista shows a dialog box that indicates the size of the remaining items to be processed and the copying speed. The values are formatted with three significant figures. This article explains how to recreate this style.

Algorithm Goals

Modern software is capable of producing sets of data that are very large in size. This can lead to long processing times for in-memory or on-disk operations. To improve the perceived performance of such large operations, you may show progress indicators within your application.

Microsoft Vista uses several progress indicators when moving or copying files. A dialog box is displayed that shows a progress bar, the number of items being copied and the estimated time remaining before the operation is complete. The dialog box also provides an expansion button that, when clicked, makes the dialog box grow larger and show even more progress information, including the number and total size of the files remaining and the speed at which the files are being processed.

The image below shows the dialog box. One interesting element is the formatting that is applied to the size of the items remaining. As the numbers as very large, it would be difficult to comprehend these values as simple numbers of bytes. Instead, the values are formatted to show three significant figures and a scale, such as bytes, KB, MB, to give the value context. In this example, the value of 9.63GB is much clearer to the user than 10,345,432,905 bytes.

Vista file copy dialog box

This article describes how the numeric formatting used by Vista for file operations can be recreated using C#.

The Algorithm and the Code

Depending upon the required use of this formatting function, you may want to create it in a new class, incorporate it in an existing class or simply add the code to a method or event. This article assumes you have a class of some kind prepared and are adding a new method to that class. The code declares a new method with a single parameter to accept the unsigned 64-bit integer to be formatted. The method returns the formatted value as a string.

To begin, create or identify the class that you will add the method to, then add the following method signature:

// Formats a file size
public string FormatFileSize(ulong bytes)
{
}

NB: If you are adding this method to a utility class you may wish to mark it as static.

File Size Scales

The formatted file size that will be created by the FormatFileSize method will include a scale value, such as bytes, kilobytes or megabytes. This scale will provide the meaning of the number once it has been reduced to three significant figures. As we are working with a 64-bit input value, seven scales will be required:

ScaleRepresents
byte1 byte
kilobyte1024 bytes
megabyte1024 kilobytes
gigabyte1024 megabytes
terabyte1024 gigabytes
petabyte1024 terabytes
exabyte1024 petabytes

To hold each of the scales, we can use an enumeration. Each increase in scale will equate to an increase in the enumeration constant value. To create the enumeration, add the following code to the class. In this case, the constant values are plural names. This will make it simpler to add the name to the final formatted string.

// Available file size scales
enum SizeScales
{
    bytes,
    kilobytes,
    megabytes,
    gigabytes,
    terabytes,
    petabytes,
    exabytes
}

Detecting a Single Byte

When processing the number of bytes passed to the FormatFileSize method, the result will almost always be formatted as a plural value. However, if the parameter value is one, the return value should be the singular "1 byte". To ensure that this is correct, we can add a simple if statement that detects this special case and immediately returns the correct value. To do so, add the following line to the FormatFileSize method.

if (bytes == 1) return "1 byte";

NB: It is not necessary to perform this check for any other size scale as large numbers will always be returned with decimal places. As these values may also be rounded, it is more appropriate to use a plural scale, as in the example "1.00 kilobytes".

23 August 2008