tags:

views:

1758

answers:

5

I assume this was already answered somewhere on SO, but I must be looking for the wrong keywords. I'll gladly remove this question if its a dup.

If not, let's answer the question here.

Example: Take input 7,326,629 and display 6.98 MB

+4  A: 
int size = new FileInfo( filePath ).Length / 1024;
string humanKBSize = string.Format( "{0} KB", size );
string humanMBSize = string.Format( "{0} MB", size / 1024 );
string humanGBSize = string.Format( "{0} GB", size / 1024 / 1024 );
TcKs
+1  A: 

I assume you're looking for "1.4 MB" instead of "1468006 bytes"?

I don't think there is a built-in way to do that in .NET. You'll need to just figure out which unit is appropriate, and format it.

Edit: Here's some sample code to do just that:

http://www.codeproject.com/KB/cpp/formatsize.aspx

Peter Crabtree
+18  A: 

I did not test this, but it should give you an idea of how to do it.

string[] sizes = { "B", "KB", "MB", "GB" };
double len = new FileInfo(filename).Length;
int order = 0;
while (len >= 1024 && order + 1 < sizes.Length) {
    order++;
    len = len/1024;
}
string result = String.Format("{0:0.##} {1}", len, sizes[order]);
David Thibault
TcKs
That's right, thank you.
David Thibault
This is exactly what I would do... Except I'd use "{0:0.#}{1}" as the format string... There's usually no real need for two digits after the dot and I don't like putting a space there. But that's just me.
configurator
Clean, concise, and exactly what I needed...thanks!
ColoradoRockie
+4  A: 
string[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
int s = 0;
long size = fileInfo.Length;

while (size >= 1024)
{
    s++;
    size /= 1024;
}

string humanReadable = String.Format("{0} {1}", size, suffixes[s]);
bobwienholt
TcKs
nope... a 64-bit signed integer cannot go beyond the ZB... which represents numbers 2^70.
bobwienholt
So why put in YB?
configurator
I like this answer best myself, but everybody here put in really in-efficient solutions really, you should use "size = size >> 10" shift is so very much faster than division... and I think that it's good to have the extra greek specifier's there, because in the near future, a posiable DLR function wouldnt need the "long size.." you could be on a 128 bit vector cpu or something that can hold ZB and larger ;)
RandomNickName42
Bitshifting was more efficient than division in the days of C coding on the metal. Have you done a perf test in .NET to see if the bitshift really is more efficient?Not too long ago, I looked at the state of the xor-swap and found it was actually slower in .NET vs using a temp variable.
Pete
+5  A: 
[DllImport ( "Shlwapi.dll", CharSet = CharSet.Auto )]
public static extern long StrFormatByteSize ( 
        long fileSize
        , [MarshalAs ( UnmanagedType.LPTStr )] StringBuilder buffer
        , int bufferSize );


/// <summary>
/// Converts a numeric value into a string that represents the number expressed as a size value in bytes, kilobytes, megabytes, or gigabytes, depending on the size.
/// </summary>
/// <param name="filelength">The numeric value to be converted.</param>
/// <returns>the converted string</returns>
public static string StrFormatByteSize (long filesize) {
     StringBuilder sb = new StringBuilder( 11 );
     StrFormatByteSize( filesize, sb, sb.Capacity );
     return sb.ToString();
}

From: http://www.pinvoke.net/default.aspx/shlwapi/StrFormatByteSize.html

Bob