Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File-size format provider

Is there any easy way to create a class that uses IFormatProvider that writes out a user-friendly file-size?

public static string GetFileSizeString(string filePath) {     FileInfo info = new FileInfo(@"c:\windows\notepad.exe");     long size = info.Length;     string sizeString = size.ToString(FileSizeFormatProvider); // This is where the class does its magic... } 

It should result in strings formatted something like "2,5 MB", "3,9 GB", "670 bytes" and so on.

like image 511
Seb Nilsson Avatar asked Sep 24 '08 17:09

Seb Nilsson


People also ask

How do I convert MB to file size?

You can retrieve the length of the file with File#length(), which will return a value in bytes, so you need to divide this by 1024*1024 to get its value in mb.

What is FileInfo length?

FileInfo has a Length property. It returns the size of a file in bytes. We use FileInfo and the Length property to measure file sizes.


1 Answers

I use this one, I get it from the web

public class FileSizeFormatProvider : IFormatProvider, ICustomFormatter {     public object GetFormat(Type formatType)     {         if (formatType == typeof(ICustomFormatter)) return this;         return null;     }      private const string fileSizeFormat = "fs";     private const Decimal OneKiloByte = 1024M;     private const Decimal OneMegaByte = OneKiloByte * 1024M;     private const Decimal OneGigaByte = OneMegaByte * 1024M;      public string Format(string format, object arg, IFormatProvider formatProvider)     {             if (format == null || !format.StartsWith(fileSizeFormat))             {                 return defaultFormat(format, arg, formatProvider);             }          if (arg is string)             {                 return defaultFormat(format, arg, formatProvider);             }          Decimal size;          try             {                 size = Convert.ToDecimal(arg);             }             catch (InvalidCastException)             {                 return defaultFormat(format, arg, formatProvider);             }          string suffix;         if (size > OneGigaByte)         {             size /= OneGigaByte;             suffix = "GB";         }         else if (size > OneMegaByte)         {             size /= OneMegaByte;             suffix = "MB";         }         else if (size > OneKiloByte)         {             size /= OneKiloByte;             suffix = "kB";         }         else         {             suffix = " B";         }          string precision = format.Substring(2);         if (String.IsNullOrEmpty(precision)) precision = "2";         return String.Format("{0:N" + precision + "}{1}", size, suffix);      }      private static string defaultFormat(string format, object arg, IFormatProvider formatProvider)     {         IFormattable formattableArg = arg as IFormattable;         if (formattableArg != null)         {             return formattableArg.ToString(format, formatProvider);         }         return arg.ToString();     }  } 

an example of use would be:

Console.WriteLine(String.Format(new FileSizeFormatProvider(), "File size: {0:fs}", 100)); Console.WriteLine(String.Format(new FileSizeFormatProvider(), "File size: {0:fs}", 10000)); 

Credits for http://flimflan.com/blog/FileSizeFormatProvider.aspx

There is a problem with ToString(), it's expecting a NumberFormatInfo type that implements IFormatProvider but the NumberFormatInfo class is sealed :(

If you're using C# 3.0 you can use an extension method to get the result you want:

public static class ExtensionMethods {     public static string ToFileSize(this long l)     {         return String.Format(new FileSizeFormatProvider(), "{0:fs}", l);     } } 

You can use it like this.

long l = 100000000; Console.WriteLine(l.ToFileSize()); 

Hope this helps.

like image 137
Eduardo Campañó Avatar answered Oct 06 '22 20:10

Eduardo Campañó