如何显示稀疏文件的非稀疏部分?

Sté*_*las 8 text-processing sparse-files

想象一个用以下方式创建的文件:

truncate -s1T file
echo test >> file
truncate -s2T file
Run Code Online (Sandbox Code Playgroud)

我现在有一个 2 tebibyte 的文件(在磁盘上占用 4kiB), "test\n"写在中间。

我将如何"test"有效地恢复它,即无需读取整个文件。

tr -d '\0' < file
Run Code Online (Sandbox Code Playgroud)

会给我结果,但这需要几个小时。

我想要的是只输出文件的非稀疏部分的东西(所以只在上面 "test\n"或更可能的是,在磁盘上分配的 4kiB 块存储该数据)。

有API可以找出文件的哪一部分被分配(FIBMAP、FIEMAP、SEEK_HOLE、SEEK_DATA...),但是哪些工具可以公开这些?

一个可移植的解决方案(至少对于支持这些 API 的操作系统)将不胜感激。

Sté*_*las 6

我能想出迄今最好的是(ksh93的,使用filefrage2fsprogs1.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
Run Code Online (Sandbox Code Playgroud)

filefrag 使用 FIEMAP ioctl 为支持它的文件系统报告文件的范围。

*unwritten*部分涵盖了(非稀疏的,但仍然充满了我不感兴趣的零)文件,这些文件已被fallocated写入但未写入。

bsdtarstar可以使用其中一些 API 的最新版本来生成一个tar文件,用于标识稀疏部分。这将提供一种更便携的解决方案,但随后必须解析生成的 tar 文件才能获得非稀疏部分。