如何将文件填充到所需大小?


15

我有一个文件要填充,直到达到16 MiB(16777216字节)。当前为16515072字节。差异为262144字节。

我该如何填充?

这似乎不起作用:

cp smallfile.img largerfile.img
dd if=/dev/zero of=largerfile.img bs=1 count=262144

2
@TB 您要物理填充还是逻辑填充?换一种说法; 该文件应仅显示16777216(可能包含孔)大小,还是应占用磁盘上的该存储量?-顺便说一句,在选择bs=1dd是在我的经验非常昂贵运行。
贾尼斯(Janis)

5
truncate -s 16M thefile
frostschutz 2015年

4
@frostschutz这将是一个很好的答案,如果您将其发布为答案。
derobert

@ derobert,StackExchange网站用户发布合法,简单的答案作为评论是怎么回事?
user1717828 2015年

@ user1717828不确定,可能是对meta的一个好问题。
derobert

Answers:


10

of=largerfile.txt将stdout 拖放到文件中:

dd if=/dev/zero bs=1 count=262144 >> largerfile.txt

1
seek是这里的正确选择。
0andriy

15

除了获得物理填充的答案外,您还可以seek通过指向文件的新结束位置并写入单个字符,将文件中的大多数填充空间留为空白(“空洞”):

dd if=/dev/zero of=largerfile.txt bs=1 count=1 seek=16777215

(这样做的好处是性能更高,特别是 bs=1,并且不会占用大量额外的磁盘空间)。

通过使用该方法,即使不添加任何字符,该方法似乎仍然有效 if=/dev/null和最终所需的文件大小:

dd if=/dev/null of=largerfile.txt bs=1 count=1 seek=16777216

使用较大块大小的物理填充解决方案的高性能变体是:

padding=262144 bs=32768 nblocks=$((padding/bs)) rest=$((padding%bs))
{
  dd if=/dev/zero bs=$bs count=$nblocks
  dd if=/dev/zero bs=$rest count=1
} 2>/dev/null >>largerfile.txt

3
正确。在这种情况下truncate -s +262144 largerfile.txt也会很快。
don_crissti 2015年

4

最好的答案是Janis(上面),因为它可以让您忘记当前文件的大小,而无需计算即可直接填充到所需的大小。

它还利用了稀疏文件的优势,而/ dev / zero则没有。

答案可能会更整洁,因为'count'允许为0并且您仍然可以得到填充:

dd if=/dev/null of=largerfile.txt bs=1 count=0 seek=16777216

(编辑:这对于GNU dd是正确的,但是的行为count=0是特定于平台的,请参见注释)


您会误会:count=0未指定,但是通常与未count指定参数时相同。更多问题:dd将文件截断为16777216字节,但是如果您希望这会在最后创建一个空洞,那么您会误会,因为您首先需要在空洞之后写入数据,然后再将其截断为不包含数据的大小。
schily

count = 0类似于指定no count参数。你是说和那dd if=/dev/zero of=somefile一样dd if=/dev/zero of=somefile count=0吗?尝试一下。
PeteC

当然!count=0 一样的,如果你没有指定在所有计数参数。至少对于从原始来源派生的所有实现,都是如此。尝试一下,似乎您从未使用过原始dd命令。
schily

我找不到任何文档将0表示count为“忽略此参数” 的唯一值。你能找到吗?如果没有这样的文档,则count=0意味着“写零块”,并且对此的任何偏离都是一个错误……(原始信息或没有)。
PeteC

1
这是2015年5月之前的POSIX文档,当时纠正了未指定的文本。
schily

1

你要用dd吗?如果要使文件具有特定的(逻辑)长度,只需在所需位置写入零即可。末尾与写入字节之间的字节将显示为具有空字节。这是使用perl的示例。

$ echo Hello > file
$ ls -l file
-rw-r--r-- 1 user group 6 Apr 16 22:59 file
$ perl -le 'open(my $f,"+<","file"); seek($f, 16777216 - 2, 0); print $f "\0"'
$ ls -ln file
-rw-r--r-- 1 user group 16777216 Apr 16 22:59 file

为什么在行中“ -2”?该脚本将写入一个字节,因此我们减去1来查找到该字节之前的位置。我们选择另一个,因为搜索位置是零索引的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.