Как отобразить не разреженные части разреженного файла?

8

Представьте себе файл, созданный с помощью:

truncate -s1T file
echo test >> file
truncate -s2T file

Теперь у меня есть файл 2 тэбибайт (который занимает 4киБ на диске), с записью "test\n"в середине.

Как бы я восстановил это "test"эффективно, то есть без необходимости читать весь файл.

tr -d '\0' < file

Даст мне результат, но это займет несколько часов.

То, что я хотел бы, это то, что выводит только не разреженные части файла (так что выше "test\n"или более вероятно, блок 4kiB, выделенный на диске, который хранит эти данные).

Существуют API-интерфейсы для определения того, какая часть файла выделена (FIBMAP, FIEMAP, SEEK_HOLE, SEEK_DATA ...), но какие инструменты предоставляют их?

Переносимое решение (по крайней мере, для операционных систем, поддерживающих эти API) приветствуется.

Стефан Шазелас
источник
Насколько это эффективно strings?
Гленн Джекман
@glennjackman, меньше, trпоскольку он все еще читает весь файл и делает больше, чем просто удаляет байты NUL.
Стефан Шазелас

Ответы:

6

Лучшее, что я мог придумать, это (ksh93, использующий filefragс e2fsprogs1.42.9 (некоторые старые версии имеют другой API) на файловых системах на основе экстентов в Linux):

#! /bin/ksh93
export LC_ALL=C
for file do
filefrag -vb1 -- "$file" |
  while IFS=": ." read -A a; do
    [[ $a = +([0-9]) ]] && [[ ${a[@]} != *unwritten* ]] &&
      command /opt/ast/bin/head -s "${a[1]}" -c "${a[7]}" -- "$file"
  done
done

filefrag сообщает экстенты файла, используя FIEMAP ioctl для файловых систем, которые его поддерживают.

В *unwritten*части крышки для (неразреженного, но до сих пор полных нулей я не заинтересованы в) файлы , которые были , fallocatedно не для записи.

Последние версии bsdtarили starмогут использовать некоторые из этих API для создания tarфайла, который идентифицирует разреженные разделы как таковые. Это сделало бы более портативное решение, но тогда нужно было бы проанализировать сгенерированный файл tar, чтобы получить не разреженные разделы.

Стефан Шазелас
источник