如何在Linux中创建指定大小的文件?

210
为了进行测试目的,我需要生成一个特定大小的文件(以测试上传限制)。在Linux上创建特定大小的文件的命令是什么?

2
快速在Linux系统上创建大文件 - Ciro Santilli OurBigBook.com
14个回答

246

对于小文件:

dd if=/dev/zero of=upload_test bs=file_size count=1

其中file_size表示您的测试文件大小(以字节为单位)。

对于大文件:

dd if=/dev/zero of=upload_test bs=1M count=size_in_megabytes

12
实际上,如果块大小很大,性能会随着其变得非常大而变差,因为它将在写入之前将那么多的数据分配并读入内存中。如果像bs=4GiB这样的大小,您可能最终会发生交换。 - Brian
45
“dd” 命令的数值上限为 2^32,因此要创建一个大于 4 GB 的文件,有一个技巧:使用命令 dd if=/dev/zero of=test bs=1M count=<以兆字节为单位的大小> - Dmytro Sirenko
2
请参考下一个答案,以获得更好、更快的方法。 - elegant dice
3
@elegantdice并不清楚下一个答案是哪个,他们可以改变自己的立场。 - vladkras
1
@vladkras 确实...我是指Jørgensen的答案,截断和预分配空间。 - elegant dice
显示剩余5条评论

222
请,现代化更简单、更快速。在Linux上,(选择一个)
truncate -s 10G foo
fallocate -l 5G bar

需要指出的是,在支持稀疏文件的文件系统上,使用truncate命令会创建一个稀疏文件,而fallocate则不会。稀疏文件是指文件的分配单元在使用之前并没有实际分配。文件的元数据会占用一定的空间,但很可能远远不及文件的实际大小。关于稀疏文件的更多信息,您应该查阅相关资源,因为这种类型的文件有其优点和缺点。非稀疏文件会提前分配其块(分配单元),这意味着从文件系统的角度来看,空间已经被保留。此外,fallocatetruncate都不会像dd那样将文件内容设置为指定的值,而是在创建时分配的文件的内容可能是任何存在于分配单元中的垃圾值,这种行为可能是有意的,也可能不是。dd是最慢的,因为它实际上会根据命令行选项将值或数据块写入整个文件流中。
这种行为可能因所使用的文件系统以及该文件系统对任何标准或规范的符合程度而有所不同。因此,建议进行适当的研究,以确保使用正确的方法。

1
我尝试了 truncate。使用上述语法它生成了一个大小为零的文件。fallocate 的“man page”说它创建的文件充满空的“空间”,而不是数据。看起来它对于一些预期情况,比如“复制一个1G文件需要多长时间”,并没有什么用处。 - Mark Stosberg
7
对我来说,fallocate 的工作效果很好,它可以创建一个正确大小的文件。 - Aater Suleman
6
这是这个问题的最佳答案。truncate/fallocate不会花费太长时间,因为它并不会写入文件的所有块。但是,如果您要将结果文件上传到某个地方,它将读取整个文件的零。 - Mike Andrews
4
如果你希望在OSX上运行这个操作,那么你需要执行这个命令:brew install coreutils。这将在命令前面添加一个“g”,所以你需要这样运行它:gtruncate -s 10G foo。希望这能帮到你! - DerekE
似乎它在 NTFS 分区上无法工作。 - eloyesp
显示剩余4条评论

44

为了跟进Tom的帖子,你也可以使用dd创建稀疏文件:

dd if=/dev/zero of=the_file bs=1 count=0 seek=12345

这将在大多数Unix系统上创建一个具有“空洞”的文件-实际上,数据在写入非零值之前不会被写入磁盘,也不会占用任何空间。


将count=0设置可以避免从文件大小中减去一个字节。 - andrewdotn
3
count=0 时,bs * seek 等于文件大小。 - Jayen

31

使用以下命令:

dd if=$INPUT-FILE of=$OUTPUT-FILE bs=$BLOCK-SIZE count=$NUM-BLOCKS

要创建一个大的(空的)文件,请设置 $INPUT-FILE=/dev/zero
文件总大小将为 $BLOCK-SIZE * $NUM-BLOCKS
新文件将被创建为 $OUTPUT-FILE


17
我需要谷歌搜索答案,所以我把它放在这里,这样可以讨论和保持更新...你知道,这是整个网站的重点吧? - Grundlefleck
4
我知道人们因为刻意追求经验值而对@Grundlefleck进行投票,但他确实有一点——Jeff和Joel设想的使用该网站的方式之一是针对你刚刚发现的某个问题提出问题并给出答案。 - Paul Tomblin
4
谢谢保罗。虽然我不太关心分数,但我很担心在谷歌上发现的东西可能存在某些缺陷,除非我在这里问,否则我永远不会发现。如果别人认为我在乱搞,他们应该自由地让我的问答社区归属于大家。 - Grundlefleck
3
引用自常见问题的回答:“问自己的编程问题并回答它也完全可以,但假装你在玩“危险边缘”游戏:把问题以问题的形式表述。” - Craig Angus
@PaulTomblin 别开玩笑了,我们不是在玩游戏,做点什么也不会得到经验值 :) - BЈовић
显示剩余3条评论

27

在OSX(以及显然还有Solaris)中,mkfile命令也是可用的:

mkfile 10g big_file

这将创建一个名为"big_file"的10 GB文件。在这里找到了此方法


这对于像OS X这样没有“truncate”和“fallocate”命令的情况非常有用。虽然dd也可以像上面描述的那样工作,但是它的单位是“m”,而不是“M”。 - user535673
错误:这将创建一个10 GiB的文件(约为10.7GB)。 - dessert

17

你可以通过编程来实现:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main() {
    int fd = creat("/tmp/foo.txt", 0644);
    ftruncate(fd, SIZE_IN_BYTES);
    close(fd);
    return 0;
}

这种方法特别适用于随后使用mmap将文件映射到内存中。
使用以下命令检查文件是否具有正确的大小:
# du -B1 --apparent-size /tmp/foo.txt

小心:

# du /tmp/foo.txt

这段代码可能会打印0,因为如果你的文件系统支持Sparse file,它会被分配。

另请参阅:man 2 openman 2 truncate


13

其中一些答案建议您使用/dev/zero作为数据源。如果您正在测试网络上传速度,并且您的应用程序正在进行任何压缩,那么这可能不是最好的选择,因为一个全零文件可以被非常有效地压缩。使用此命令生成文件:

 dd if=/dev/zero of=upload_test bs=10000 count=1

我可以将upload_test压缩到约200字节。 因此,您可能会发现自己认为正在上传10KB文件,但实际上要小得多。

我的建议是使用/dev/urandom而不是/dev/zero。 我无法对/dev/urandom的输出进行很大程度的压缩。


我的嵌入式系统没有/dev/zero,所以使用/dev/urandom是好的。 - Fredrick Gauss

12

你可以这样做:

[dsm@localhost:~]$ perl -e 'print "\0" x 100' > filename.ext

用你想写入的字节数替换100。


还有实际填充字节。我需要"\xff",工作正常。谢谢! :) - Ray

9

如果你不想等待磁盘,可以使用fallocate

例如:

fallocate -l 100G BigFile

使用方法:

Usage:
 fallocate [options] <filename>

Preallocate space to, or deallocate space from a file.

Options:
 -c, --collapse-range remove a range from the file
 -d, --dig-holes      detect zeroes and replace with holes
 -i, --insert-range   insert a hole at range, shifting existing data
 -l, --length <num>   length for range operations, in bytes
 -n, --keep-size      maintain the apparent size of the file
 -o, --offset <num>   offset for range operations, in bytes
 -p, --punch-hole     replace a range with a hole (implies -n)
 -z, --zero-range     zero and ensure allocation of a range
 -x, --posix          use posix_fallocate(3) instead of fallocate(2)
 -v, --verbose        verbose mode

 -h, --help           display this help
 -V, --version        display version

9
dd if=/dev/zero of=my_file.txt count=12345

4
请记住,dd命令默认的块大小为512字节,因此这个命令会创建一个大小为12345*512字节的文件。 - nobody

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接