Класс, реализующий IFormatProvider для вывода размера файла

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

При работе с файловой системой, все размеры файлов в C# возвращаются в байтах. С одной стороны — это полностью оправданный и правильный подход, а, с другой стороны — пользователю не всегда удобно видеть перед собой огромные числа, обозначающие, например, объем свободного места на диске. Для предоставления информации о размере файла или объеме диска в удобном для пользователя виде (в Кб, Мб, Тб и т.д.) существует несколько подходов, например, можно написать свой метод перевода величин. Мы же сегодня рассмотрим класс, который реализует интерфейс IFormatProvider в C# и может использоваться при форматировании строк, содержащих размер файла.

Класс, реализующий IFormatProvider для вывода размера файла

Представленный ниже класс позволяет представлять размеры файлов в виде строки с определенными суффиксами (kB, MB, TB, GB и TB):

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;
        private const decimal OneTeraByte = OneMegaByte * 1024M * 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 > OneTeraByte)
            {
                size /= OneTeraByte;
                suffix = "TB";
            } else 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();
        }

    }

Достаточно добавить этот класс в свой проект и, в дальнейшем, его функциональность можно использовать для форматирования строк, используя описатель fs.

Пример использования класса FileSizeFormatProvider

Рассмотрим пример использование класса FileSizeFormatProvider для вывода информации о логических дисках. Первый вариант использования класса:

class Program
{
    static void Main(string[] args)
    {
        DriveInfo[] drives = DriveInfo.GetDrives();
        foreach (DriveInfo drive in drives)
        {
            Console.WriteLine($"Название: {drive.Name}");
            Console.WriteLine($"Тип: {drive.DriveType}");
            if (drive.IsReady)
            {
                Console.WriteLine(string.Format(new FileSizeFormatProvider(), "Объем диска: {0:fs}", drive.TotalSize));
                Console.WriteLine(string.Format(new FileSizeFormatProvider(), "Свободное пространство: {0:fs}", drive.TotalFreeSpace));
                Console.WriteLine($"Метка: {drive.VolumeLabel}");
           }
        }
    }
}

Можно немного упростить использование класса и написать свой метод расширения, например, так:

using System;
using System.IO;

namespace FileSystem
{
    //метод расширеия для long
    public static class ExtensionMethods
    {
        public static string ToFileSize(this long l) 
        {
            return string.Format(new FileSizeFormatProvider(), "{0:fs}", l);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            DriveInfo[] drives = DriveInfo.GetDrives();
            foreach (DriveInfo drive in drives)
            {
                Console.WriteLine($"Название: {drive.Name}");
                Console.WriteLine($"Тип: {drive.DriveType}");
                if (drive.IsReady)
                {
                    Console.WriteLine($"Объем диска: {drive.TotalSize.ToFileSize()}") ;
                    Console.WriteLine($"Свободное пространство: {drive.TotalFreeSpace.ToFileSize()}");
                    Console.WriteLine($"Метка: {drive.VolumeLabel}");
                }
            }
        }
    }
}

В любом случае, результат будет один и тот же:

Название: C:\
Тип: Fixed
Объем диска: 111,12GB
Свободное пространство: 36,40GB
Метка:

Итого

Сегодня мы рассмотрели класс, реализующий интерфейс IFormatProvider для форматирования размеров файлов в удобном для пользователя виде. Для использования класса его необходимо добавить в проект и, при необходимости, написать свой метод расширения.

При написании этой статьи использовались материалы с сайта stackoverflow.

 

уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
guest
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии