Почему файл TAR должен быть меньше своего содержимого?
Вопрос
У меня есть каталог, который я архивирую:
$ du -sh oldcode
1400848
$ tar cf oldcode.tar oldcode
Таким образом, размер каталога составляет 1,4 гб.Однако файл значительно меньше по размеру:
$ ls -l oldcode.tar
-rw-r--r-- 1 ieure ieure 940339200 2002-01-30 10:33 oldcode.tar
Всего 897 мб.Он никоим образом не сжат:
$ file oldcode.tar
oldcode.tar: POSIX tar archive
Почему файл tar меньше своего содержимого?
Решение
Вы получаете разницу из-за того, как работает файловая система.
В двух словах, ваш диск состоит из кластеров.Каждый кластер имеет фиксированный размер, скажем, в 4 килобайта.Если вы сохраните файл размером 1 кб в таком кластере, 3 кб будет неиспользуемым.Точные детали зависят от типа используемой вами файловой системы, но большинство файловых систем работают именно так.
3 кб потраченного впустую пространства - это немного для одного файла, но если у вас много очень маленьких файлов, то потери могут стать значительной частью использования диска.
Внутри tar-архива файлы хранятся не в кластерах, а один за другим.Вот откуда берется разница.
Другие советы
Не имея представления о том, какой tar вы используете или какую систему Unix вы используете, вот мое предположение:oldcode содержит множество файлов меньшего размера, которые сами по себе неэффективно используют дисковое пространство, поскольку дисковое пространство выделяется каким-то блоком, а не побайтно.В файле tar они объединены и максимально используют отведенное им дисковое пространство.
Это как-то связано с размером блока вашей файловой системы. man 1 du в MacOSX 10.5.6 говорится:
Утилита du отображает файловую систему использование блока для каждого аргумента файла и для каждого каталога в файловой иерархии, коренящегося в каждом аргументе каталога.Если файл не указан, отображается использование блоков иерархии, коренящейся в текущем каталоге.
[mirko@borg foo]$ ls -la
total 0
drwxr-xr-x 2 mirko wheel 68 Jan 30 21:20 .
drwxrwxrwt 10 root wheel 340 Jan 30 21:16 ..
[mirko@borg foo]$ du -sh
0B .
[mirko@borg foo]$ touch foo
[mirko@borg foo]$ ls -la
total 0
drwxr-xr-x 3 mirko wheel 102 Jan 30 21:20 .
drwxrwxrwt 10 root wheel 340 Jan 30 21:16 ..
-rw-r--r-- 1 mirko wheel 0 Jan 30 21:20 foo
[mirko@borg foo]$ du -sh
0B .
[mirko@borg foo]$ echo 1 > foo
[mirko@borg foo]$ ls -la
total 8
drwxr-xr-x 3 mirko wheel 102 Jan 30 21:20 .
drwxrwxrwt 10 root wheel 340 Jan 30 21:16 ..
-rw-r--r-- 1 mirko wheel 2 Jan 30 21:20 foo
[mirko@borg foo]$ du -sh
4.0K .
Как вы видите, даже файл размером в 2 байта занимает целый блок в 4 кб.Есть некоторые файловые системы, которые избегают этой пустой траты пространства за счет перераспределение блоков.
Есть 2 возможности.
Небольшие файлы
Скорее всего, это это не так меньше, чем его содержимое. Как писал Нильс Пипенбринк, du
отображает объем пространства, выделяемого файловой системой, который, поскольку файлы хранятся в блоках файловой системы, превышает логический размер файла.
Чтобы просмотреть логический размер файла, используйте du --apparent-size
.В этом случае результат должен быть меньше, чем файл tar.
Разреженные файлы
Файлы Tar могут хранить разреженные файлы.Если архив был создан с использованием --sparse
, будут записаны пробелы в разреженных файлах, поэтому архив может быть меньше логического размера файлов.
Если информация о разреженности в вашей извлеченной копии была каким-то образом утеряна (напримересли вы извлекли архив в файловую систему, которая не поддерживает разреженные файлы, или если он был заархивирован, а затем разархивирован и т.д.), То df
сообщит о расширенном размере.
du подсчитывает блоки диска, а не размер файла duder.