[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Чем сжать "файл с дырками"?



On Mon, 27 Oct 2008, Victor Wagner wrote:

On 2008.10.27 at 18:02:42 +0500, Andrey Teleshov wrote:

On Mon, 27 Oct 2008 11:49:17 +0300
"Dmitry Fedorov" <dm.fedorov@gmail.com> wrote:

Хм... Видимо, я что-то недопонимаю в том, как FS хранит такой файл.
Размер файла 4294967296 байт, т.е. 4194304 кбайт. Ясно, что не все эти
килобайты заполнены, часть этого пространства -- дырки.

Но FS хранит один такой файл в 1119512 однокилобайтных блоках, а другой
точно такой же (копию) -- в 1051616 блоках. Странно.

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

Ура! Я продырявил файл!

~/tmp$ dd if=/dev/zero of=orig.bin count=20
20+0 записей считано
20+0 записей написано
 скопировано 10240 байт (10 kB), 0,0001567 секунд, 65,3 MB/s

~/tmp$ hexedit orig.bin
(два байта, нулевой и последний, поменял с 0x00 на 0xAA)

~/tmp$ cp --sparse=always orig.bin copy.bin

~/tmp$ ls -1s
 8 copy.bin
12 orig.bin

Что мы видим? Файл размером 10 kB с двумя ненулевыми и остальными
нулевыми байтами продырявился, но файловой системе нужно целых 8
блоков, чтобы его хранить. А не один блок, как я ожидал. Ну что ж,

Тут есть следующие тонкости
1. Блок в понимании ls и блок в понимании файловой системы - это не одно
и то же. Похоже, что в данном случае ls считает размером блока 1Кб (у
нее есть ключик --block-size), а умолчательный размер блока FS у нас
нынче 4Кб. Так что 8 блоков с точки зрения ls это два реальных блока.

2. Файл с дыркой с одним значимым байтом в начале, и одним в конце,
должен занимать именно ДВА БЛОКА. Просто по самому принципу организации
дырок - если нам попался блок, состоящий из одних нулей, то мы его не
размещаем. В начале файла есть ненулевые данные  - мы блок разместили.
Второй  блок не разместили, а третий - опять разместили. Там есть
ненулевой байт.

В результате и получаем 8 кб занятого места на диске. Если файл будет не
на 10 килобайт, а на 10 мегабайт, результат будет тот же самый.


  А проверить?

  > dd if=/dev/zero of=orig.bin count=2000
  > hexedit orig.bin
  > cp --sparse=always orig.bin copy.bin
  > ls -s orig.bin copy.bin
  12 copy.bin  1008 orig.bin

  Эксперимент показал, что до count=96 число
  блоков в copy.bin будет 8, а после 12.
  При 16384 число блоков уже 16.
  В общем, что-то более сложное ...


Reply to: