В PowerShell есть замечательная возможность нативно оперировать с этими префиксами. Достаточно написать размер в килобайтах или мегабайтах, PowerShell автоматически переведёт его в байты:
[vPodans] 5kb 5120 [vPodans] 10mb 10485760 [vPodans] 40gb 42949672960 [vPodans]
Видите, все значения сами переводятся в байты. Особо не перестарайтесь, потому что TB не является константой и автоматически не преобразовывается. Но когда мы собираем информацию о системе, например, объём физической памяти или жёстких дисков средствами WMI, то данные обычно указываются в байтах и приходится вручную их как-то переводить в килобайты, мегабайты или гигабайты. Штатного функционала для решения данной задачи нету, поэтому приходится использовать примерно такой ход:
(2048 / 1kb).tostring("F00")
и в результате мы получим число 2. Мы 2048 байт разделили на килобайты, чтобы получить значение в килобайтах (если делим на 1MB, то значение получим в мегабайтах соответственно) с округлением до целого числа. Для округления до определённого знака после запятой, то в скобках нужно указать точность, например:
[vPodans] (20000 / 1kb).tostring("F00") 20 [vPodans] (20000 / 1kb).tostring("F01") 19,5 [vPodans] (20000 / 1kb).tostring("F02") 19,53 [vPodans] (20000 / 1kb).tostring("F03") 19,531 [vPodans]
используя эти данные можно написать простенькую функцию, которая будет делать обратное преобразование. Причём она это будет делать автоматически, т.е. сама выбирать в чём отображать значение, в байтах, килобайтах, мегабайтах или гигабайтах. Критерии выбора префикса очень простые - числа от 1 до 1000. Если число выше, то увеличиваем префикс до тех пор, пока не получим число от 1 до 1000. Например, 10485760 делим на 1kb и получаем 10240 килобайт. Такое представление не очень понятное. Поэтому мы ещё раз разделим на 1kb и получим цифру 10, но префикс уже будет - мегабайты. Вот такую функцию предложил Rob Campbell на ньюсгруппах (я её немного подрихтовал, чтобы выглядела более элегантно):
function to_kmg ($bytes, [int]$precision = 0) { foreach ($i in ("Bytes","KB","MB","GB","TB")) { if (($bytes -lt 1024) -or ($i -eq "TB")){ $bytes = ($bytes).tostring("F0" + "$precision") return $bytes + " $i" } else { $bytes /= 1KB } } }
функция просто по очереди перебирает префиксы и проверяет, чтобы число было в пределах от 0 до 1024 (для двоичной системы мне кажется, что лучше использовать именно 1024, а не 1000). Если нет (а оно значит больше, чем 1024), то добавляем следующий префикс и уменьшаем число снова на 1024. Вот так просто это делается. Попробуем проверить функцию на примерах, которые были показаны в самом начале поста:
[vPodans] function to_kmg ($bytes, [int]$precision = 0) { >> foreach ($i in ("Bytes","KB","MB","GB","TB")) { >> if (($bytes -lt 1000) -or ($i -eq "TB")){ >> $bytes = ($bytes).tostring("F0" + "$precision") >> return $bytes + " $i" >> } else { >> $bytes /= 1KB >> } >> } >> } >> [vPodans] to_kmg 5120 5 KB [vPodans] to_kmg 10485760 10 MB [vPodans] to_kmg 42949672960 40 GB [vPodans]
Второй аргумент ($precision) позволяет указывать точность значения в знаках после запятой. Вот почти и всё. Однако, есть одно "но". WMI некоторые размеры отдаёт не в байтах (как для дисков), а в килобайтах (как для физической памяти). Поэтому для работы этой функции аргумент $bytes должен быть либо точного размера в байтах, либо с явным указанием префикса (например, 100kb).
Кстати говоря, тут будет полезным почитать по двоичным и десятичным префиксом. Порядок применения префиксов описан в документе IEC-60027-2:
По этим ссылкам достаточно понятно объясняется что такое десятичный префикс и двоичный, а так же и проблемы их использования в компьютерной технике.
А я уже писал эту функцию :Р http://xaegr.wordpress.com/2007/12/07/human-readable/ Кстати в 2.0 можно так: [PS <10> C:\Root] 1tb 1099511627776 [PS <11> C:\Root] 1pb 1125899906842624
Не знал, честно. :( пойду поищу стенку какую, что ли..
Comments: