11 декабря 2009 в 20:37

Разреженные файлы в NTFS

В NTFS есть поддержка разреженных файлов (sparse files). Это такие файлы, которые занимают меньше дискового пространства, чем их собственный размер. Данная технология не имеет отношения к встроенной в NTFS поддержке компрессии файлов, так как экономия места на диске в sparse-файлах основана на другом принципе. Никакого сжатия данных не осуществляется. Вместо этого, в файле высвобождаются области, занятые одними лишь нулями (0x00). Приложение, читающее разреженный файл, дойдя до области с нулями, прочитает нули, но реального чтения с диска не произойдёт.

Таким образом можно создавать файлы гигантского размера, состоящие из нулей, но на диске они могут занимать всего лишь несколько килобайт. Реальное дисковое пространство выделяется тогда, когда вместо 0x00 записываются какие-то другие данные. Разреженность поможет сэкономить дисковое пространство только в таких файлах, в которых есть действительно большие пустые области.

Демонстрировать работу с разреженными файлами я буду с помощью системной утилиты fsutil в командной строке.

Создадим с помощью утилиты пустой файл большого размера:
fsutil file createnew test.nul 10000000000

Присвоим файлу атрибут «sparse»:
fsutil sparse setflag test.nul

Сам по себе атрибут ещё не приводит к экономии дискового пространства. Нужно ещё разметить внутри файла область, которая будет освобождена. У нас весь файл пустой, так что область можно задать в размер файла.
fsutil sparse setrange test.nul 0 10000000000

Готово. Смотрим результат.
image

Как проделывать эти операции в своих программах с помощью API функций, можете посмотреть в исходном коде небольшой утилиты, которую я написал в 2006-м. Она тоже консольная, и тоже как fsutil умеет присваивать атрибут sparse и задавать диапазон освобождаемой области. Кроме того, моя программка может сама искать в файле пустые области больше некоторого заданного размера и освобождать их. Отпадает необходимость самому вычислять смещения.

Ссылки:
+43
5338
38
amdf 30,8

Комментарии (48)

+1
dimag0g, #
Простите, а где, собственно, ссылка?
+2
SamDark, #
Скорее всего вот: amdf.pp.ru/sparser.php
0
amdf, #
Вставлял ссылку, не заметил.
НЛО прилетело и опубликовало эту надпись здесь
+6
amdf, #
Мне попадался файл — образ DVD диска для запуска пиратской версии игры. Там информации было немного, только в начале, а остальное состояло из нулей. Образ надо было монтировать как есть, удалять нули нельзя. Вот я его таким образом укоротил.
0
yogurt, #
А обычная компрессия NTFS разве не дала бы тот же результат?
Способ безусловно интересный, но возможности практического применения мне кажутся не очевидными.
+8
amdf, #
С компрессией нули во-первых читаются с диска, во-вторых разжимаются, на что тратятся системные ресурсы. А тут драйвер файловой системы просто отдаёт нули, и всё.
+3
kurokikaze, #
На самом деле sparse-структуры нужно класть в файлы уже нормально сериализованными. Но и этому может найтись применение где нибудь.
0
Skif300000, #
Интересно буду знать.
+1
zencd, #
В принципе для качалок может пригодиться… Однако работа с большими файлами — это обычно и длительная работа. Обычно такое пространство резервируется сразу. Но неприятно будет, оставив файл качаться-рендериться, вернувшись, увидеть что операция FAIL из-за нехватки места.

Наверное иначе чем в энтерпрайзе это и не пригодится…
+1
somniator, #
В чем преимущество записывать заполненные нулями файлы на диск?
+14
IGHOR, #
чтобы похвастаться и сказать: «смотри! у меня 2Тб на флешке занято»
+11
x40c, #
Как вариант, для параноиков: если не хочешь, чтоб твой файл кто-то унёс. :)
НЛО прилетело и опубликовало эту надпись здесь
+3
alienator, #
В последней команде пропущено имя файла.

fsutil sparse setrange test.nul 0 10000000000
+3
diss, #
ой как интересно
почитайте про thin provisioning и deduplication, будете удивлены.
в мире еще столько неизведанного…
+1
romx, #
Но в NTFS-то их пока нет.
+7
Ctacus, #
вот щас у меня будет шара в пару терабайтов на DC++ хабе =)
+1
Ctacus, #
облом, все это дело будет хешироваться часов 20 =(
–16
diss, #
вы-идиот
Вы ничего не знаете про хранение данных
+1
Ex3NDR, #
не кормите его!
0
4tm, #
мужик, ты жжешь! мне было удивительно интересно это узнать)
0
xiWera, #
извините, я не понял из статьи, это надо специально такие файлы создавать? Или как во всех юнихах: делаешь seek за конец файла — получаешь sparse файл?
0
amdf, #
Специально устанавливается атрибут, а потом ещё размечаешь sparse-область.
–3
VolCh, #
>Или как во всех юнихах: делаешь seek за конец файла — получаешь sparse файл?

Только что проверил — на FAT разделах не пашет ;) Видимо это не свойство ОС, а свойство файловой системы, которое, впрочем, ось должна уметь использовать.
0
AterCattus, #
Виндозная win32api.SetFilePointer заполняет все пространство нулями. Она именно записывает данные в полном объеме. Типа «для безопасности». Отучить ее от этого нельзя. А под файловые истсемы *nix на самом деле имеет место простое указание в файловом дескрипторе, что файл занимает от сих и до сих, без непосредственной очистки места.
НЛО прилетело и опубликовало эту надпись здесь
0
rexxer2, #
Небольшое дополнение для тех, кто будет использовать спарзфайлы.

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

Вопрос насколько фрагментация опасна для NTFS спорный, но, на мой взгляд, замедление все-таки имеет место
0
gureedo, #
Хочу подметить, что emule не помечает области разряженными.
И еще при скачивании со скоростью 100 МБит/c размазанность файла не спасает.
0
rexxer2, #
В параметрах emule есть пункт «Использовать разреженные файлы»
+4
Mithgol, #
eMule самым превосходным образом помечает файлы разрежёнными (sparce), если поставить соответствующую галочку:

[eMule sparce]

У меня, как видите, эта галочка не поставлена, и не только чтобы не происходило дичайшей фрагментации, но и чтобы на диске всегда либо хватало места, либо с самого начала закачка останавливалась из-за его нехватки. А не то несколько sparse-закачек могли бы со временем мешать друг другу, вступая в борьбу за свободное место на диске.
–4
catsmile, #
Ваш скриншот — уж извините, но адский ад.
0
amdf, #
И в µTorrent такое есть

+3
romx, #
Ну, справедливости ради, sparse files в NTFS придумывалось не для eMule ;)
А для разных специфических применений, типа (сходу что пришло в голову) льется со спутника или радиотелескопа прерывистый поток данных, во многие терабайты объемом, но по преимуществу пустой внутри, только изредка в нем проскакивают небольшие, но очнь важные кусочки, с которыми потом предстоит работать.

То что большинство впервые узнало про sparse files, несмотря на то, что он в NTFS с середины 90-х (с NT4.0) показывает слабую применимость его для бытового использования.
НЛО прилетело и опубликовало эту надпись здесь
0
romx, #
Это что же за устройство «жгущее матрицу» с NTFS-ом на нем? ;)
0
stepio, #
Формулировка неточная, но вообщем ROX прав — такая технология может быть полезна в SSD. Только это все равно никак не отменяет «дикую фрагментацию»…
–1
Roy, #
О! Спасибо, как раз сам собирался писать — перенес тут диски виртуалок на другой винт :)
Вот только в архиве лежит CS.exe:

Stream copy program: www.flexhex.com

Usage:
CS fromstream tostream

Example:
CS c:\some.txt d:\file.dat:text

Сдается мне, что это не оно.
0
Roy, #
Тьфу! Извиняюсь, имя архива перепутал.
0
romx, #
Судя по названию это тема еще одного поста про малоизвестные «фишки» NTFS — NTFS Streams. ;)
0
jcmvbkbc, #
Обычный win32 CopyFile, которым пользуется проводник, успешно копирует потоки файлов NTFS сам.
0
Roy, #
А эта штука умеет sparsed файлы копировать, чего CopyFile не умеет.
Правда меееедленно :)
+1
VolCh, #
>Сам по себе атрибут ещё не приводит к экономии дискового пространства. Нужно ещё разметить внутри файла область, которая будет освобождена.

С вот этим непонятно. Допустим есть файл размером 10 Гб, который не весь забит нулями — если задать область целиком файл, то что произойдёт? И наоборот, файл из одних нулей, задали область, а потом начали в эту область писать?

P.S. Понятно, что самому можно поэкспериментировать, но может готовый ответ есть :)
0
fermion, #
А если копировать такой файл каким нибудь ТоталКомандером, то во первых файл становится своего указанного размера (возможно ТК сбивает атрибуты при копировании), а во вторых у меня после нескольких копирований потерялось свободное место на диске, помогло только chkdsk.
+2
DrShark, #
ТК не поддерживает копирование/перемещение разреженных файлов с сохранением размера, и не факт что будет в ближайшем будущем.
Но это умеет FAR Manager (начиная с версии 2.0, впрочем есть спец. билд линейки 1.7.x).
0
Roy, #
А из основной линейки 1.7 выкинули что ли? Было же…
0
DrShark, #
У меня нет доступа к полному списку изменений ветки 1.7x, по-этому утверждать, что поддержка спарсов там вообще была — не стану.
Вот магнит той спец. версии, которая выкладывалась на форуме: magnet:?xt=urn:btih:VYQYVBA65FT2YISYUBQECDM3E3VDBY7B
+3
ainu, #
Значит вот, для ленивых, создаём батник со следующим кодом:
set bigfile=video(%random%).avi
set razmer=800000000
fsutil file createnew "%bigfile%" %razmer%
fsutil sparse setflag "%bigfile%"
fsutil sparse setrange "%bigfile%" 0 %razmer%

Варьируя первую и вторую строчку, можно менять размеры и названия файлов. По умолчанию — 762-меговые файлы, имена которых задаются случайно.
Кидаем в папку, в которой хотим это дело создать и запускаем хоть сто раз. Единственно, если хотим сделать псевдо-500меговый файл, то на диске должно быть свободно 500 мегов. На одну секунду.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.