Что нового

Представление размера файла в понятный вид

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Может есть и другие варианты, но я остановился на этом :smile:

Код:
#cs
    Единицы измерения информации:
	
	Десятичная:
    Бит       - 10^0
    Килобайт  - 10^3
    Мегабайт  - 10^6
    Гигабайт  - 10^9
    Терабайт  - 10^12
    Петабайт  - 10^15
    Эксабайт  - 10^18
    Зеттабайт - 10^21
    Йоттабайт - 10^24
	
	Двоичная:
    Бит       - 2^0
    Килобайт  - 2^10
    Мегабайт  - 2^20
    Гигабайт  - 2^30
    Терабайт  - 2^40
    Петабайт  - 2^50
    Эксабайт  - 2^60
    Зеттабайт - 2^70
    Йоттабайт - 2^80	
	
	Источник: http://ru.wikipedia.org/wiki/Единицы_измерения_количества_информации
#ce

#include <Misc.au3>

$iSize = __format_GetFileSize(@ScriptDir & '\AutoIt.chm')
MsgBox(0, 'Info', 'File size: ' & $iSize)

Func __format_GetFileSize($sFile, $iFlag = 0)
	Local $iSize, $fRet
	If FileExists($sFile) Then
	    $iSize = FileGetSize($sFile)
	    $fRet = StringFormat('%0.2f Тб', _Iif($iFlag = 1, ($iSize / 10^12), ($iSize / 2^40)))
	    If ($fRet < 0.1) Then $fRet = StringFormat('%0.2f Гб', _Iif($iFlag = 1, ($iSize / 10^9), ($iSize / 2^30)))
		If ($fRet < 0.1) Then $fRet = StringFormat('%0.2f Мб', _Iif($iFlag = 1, ($iSize / 10^6), ($iSize / 2^20)))
		If ($fRet < 0.1) Then $fRet = StringFormat('%0.2f Кб', _Iif($iFlag = 1, ($iSize / 10^3), ($iSize / 2^10)))
		If ($fRet < 0.1) Then $fRet = StringFormat('%0i Б', _Iif($iFlag = 1, ($iSize / 10^0), ($iSize / 2^0)))
    Else 
	    Return SetError(@error, @extended, -1)
	EndIf
	Return $fRet
EndFunc
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
OffTopic:
сейчас убери, послезавтра выложишь
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
OffTopic:

Что - то я тебя не пойму, можешь нормально написать?
 

Zaramot

I ♥ AutoIt
Сообщения
1,160
Репутация
660
Файл размером с 161 Кб, а мне выдает 0,17 Мб :blink:
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Теперь измеряет и в двоичной и десятичной единице измерения, если Flag = 0 то в двоичной если 1 то в десятичной
 

winstan

Эксплотатор)
Сообщения
406
Репутация
79
Или я не понел или память мы измеряем ошибочно по мнению создателя статьи...
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Откройте свойства любого файла там где указывается его размер "На диске:" есть 2 значения, 1 - двоичное, а 2 в скобках десятичное, оно показывает размер до последнего байта. Кстати функция FileGetSize() возвращает значение в десятичном представлении.

Можно даже тест провести:

 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Viktor1703
в скобках это не десятичное, а просто размер, в байтах. говорить про двоичную или десятичную приставку имеет смысл только тогда, когда это самая приставка есть.


Добавлено:
Сообщение автоматически объединено:

и еще, особого смысла в этих десятичных представлениях нет. надо всего лишь точку двигать туда сюда, ну или ±1 при округлении. а вот с двоичными приставками (они кажись наз-ся по странному кибибайт, мибибайт, гибибайт и т.д.) то можно. и кстати, все (?) машины показывают именно эти самые ...бибайты, хотя и наз-ся по старинке кило, мега и прочее
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
В мегабайтах тоже, смотрите приставку в конце числа.

1.32 Мб - 1 целый мегабайт, 320.. килобайт
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
Viktor1703
Я свою использую
Код:
#include <File.au3>
#include <GUIConstantsEx.au3>
#Include <GuiListView.au3>

$aFiles = _FileListToArray (@SystemDir, "*.*", 1)

GUICreate ("FileSize")
$ListView = GUICtrlCreateListView ("File|Size", 5, 5, 385, 390, -1, $LVS_EX_FULLROWSELECT)
_GUICtrlListView_SetColumnWidth ($ListView, 0, 280)
_GUICtrlListView_SetColumnWidth ($ListView, 1, 70)
GUISetState()

For $i = 1 To $aFiles[0]
    GUICtrlCreateListViewItem ($aFiles[$i] & "|" & _ConvertFileSize(FileGetSize (@SystemDir&'\'&$aFiles[$i])), $ListView)
Next

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE

Func _ConvertFileSize($iBytes)
	Local Const $iConst = 0.0000234375 ; (1024 / 1000 - 1) / 1024
    Switch $iBytes
        Case 110154232090684 To 1125323453007766
            $iBytes = Round($iBytes / (1099511627776 + $iBytes * $iConst)) & ' TB'
        Case 1098948684577 To 110154232090683
            $iBytes = Round($iBytes / (1099511627776 + $iBytes * $iConst), 1) & ' TB'
        Case 107572492277 To 1098948684576
            $iBytes = Round($iBytes / (1073741824 + $iBytes * $iConst)) & ' GB'
        Case 1073192075 To 107572492276
            $iBytes = Round($iBytes / (1073741824 + $iBytes * $iConst), 1) & ' GB'
        Case 105156613 To 1073192074
            $iBytes = Round($iBytes / (1048576 + $iBytes * $iConst)) & ' MB'
        Case 1048040 To 105156612
            $iBytes = Round($iBytes / (1048576 + $iBytes * $iConst), 1) & ' MB'
        Case 102693 To 1048039
            $iBytes = Round($iBytes / (1024 + $iBytes * $iConst)) & ' KB'
        Case 1024 To 102692
            $iBytes = Round($iBytes / (1024 + $iBytes * $iConst), 1) & ' KB'
        Case 0 To 1023
            $iBytes = Int($iBytes / 1.024)
    EndSwitch
    Return $iBytes
EndFunc   ;==>_ConvertFileSize


Правда в диапазоне байтов хочу сделать как есть, чтоб пользователи не задавали лишних вопросов.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
ТС!
Зачем выкладывать тут обрывки таблиц?
В заголовке таблице ясно написано что это таблица для другого случая
9d8a589b7509.jpg


Двоичный подход

Приставки «кило-», «мега-», «гига-» понимаются как двоичные:

В файловых менеджерах и другом программном обеспечении для сокращённого задания размера файлов. То есть, если программа говорит, что размер файла равен 100 «КБ» (KB), то его размер приблизительно равен 102400 байт.

Десятичный подход

Приставки «кило-», «мега-», «гига-» понимаются как десятичные:

Ёмкость жёстких дисков, флеш-карт и оптических дисков задаётся именно в десятичных мегабайтах (исключение: компакт-диски, их объём задается в двоичных мегабайтах).
При неформальном общении (например, про файл в 100 тысяч байт могут сказать «файл в 100 килобайт»).
При обозначении скоростей телекоммуникационных соединений, например, 100 Мбит/с в стандарте 100BASE-TX («медный» Fast Ethernet) соответствует скорости передачи именно 100 000 000 бит/с, а 10 Гбит/с в стандарте 10GBASE-X (Ten Gigabit Ethernet) — 10 000 000 000 бит/с.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Какая разница какая таблица, возьмите любой файл, посмотрите его вес, допустим 2124043 кб - (2.12 Мб), если его вес проверить через FileGetSize() то он будет на десятки/сотни килобайт больше, в функции есть и двоичное и десятичное представление, и вообще в чём спор если эта функция не предназначена для сравнения веса файлов!? :-X
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
Viktor1703
если его вес проверить через FileGetSize() то он будет на десятки/сотни килобайт больше
с чего бы это? Вес в байтах один в один, а в функции с округлением до десятых долей, как там вообще что-то сравнивать? Оно для внешнего восприятия, и для общего сравнения, что такой то файл больше такого то в 100 раз, а не для того чтобы сравнивать размер для идентичности по размеру.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Вот что использую я:

Код:
ConsoleWrite(_StringGetFormattedSize(1023) & @LF) ; Bytes
ConsoleWrite(_StringGetFormattedSize(1748) & @LF) ; KBytes
ConsoleWrite(_StringGetFormattedSize(1024 * 1369) & @LF) ;MBytes
ConsoleWrite(_StringGetFormattedSize(1024 * 1369 * 1876) & @LF) ;GBytes
ConsoleWrite(_StringGetFormattedSize(1024 * 1369 * 1624 * 1656) & @LF) ;TBytes
ConsoleWrite(_StringGetFormattedSize(1024 * 1369 * 1624 * 1656 * 1543) & @LF) ;PBytes (wrong?)
ConsoleWrite(_StringGetFormattedSize(1024 * 1369 * 1624 * 1656 * 1543 * 1357) & @LF) ;EBytes (wrong?)

Func _StringGetBytesDisplaySize($iInputSize, $iInputUnit = 0, $iRound = 2, $iInputBits = False, $iOutputBits = False, $iOutputUnit = -4)
	Local $aUnitNames[9] = ["", "K", "M", "G", "T", "P", "E", "Z", "Y"]
	Local $iBytes = $iInputSize * 1024 ^ $iInputUnit
	Local $sB = "B"
	
	If $iInputBits Then $iBytes /= 8
	
	If $iOutputBits Then
		$iBytes *= 8
		$sB = "b"
	EndIf
	
    If $iOutputUnit < 0 Then
		Local $iOutputMax = Abs($iOutputUnit)
		$iOutputUnit = Int(Log($iBytes) / Log(1024))
		If $iOutputUnit > $iOutputMax Then $iOutputUnit = $iOutputMax
	EndIf
	
	If $aUnitNames[$iOutputUnit] = "" Then $sB = "Bytes"
	Return String(Round($iBytes / 1024 ^ $iOutputUnit, $iRound)) & " " & $aUnitNames[$iOutputUnit] & $sB
EndFunc
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Viktor1703
мне кажется ты путаешь физический размер файла и размер файла занимаемый на диске. второй связан с размером кластера жесткого диска и с фактом, что на диске информация не может хранится в долях этого кластера. то есть к примеру, если размер кластера 4 КБ, то любой файл может занимать место на диске только кратное этим самым 4 кб. отсюда и разница. чем файл фрагментированнее, тем больше эта разница
 
Верх