在Linux系统上快速创建大文件


437

如何在Linux(Red Hat Linux)系统上快速创建大文件?

dd可以完成这项工作,但是/dev/zero当您需要一个大小为数百GB的文件进行测试时,读取和写入驱动器可能会花费很长时间。

我不在乎文件的内容,我只想快速创建它。如何才能做到这一点?

为此,使用稀疏文件将不起作用。我需要为文件分配磁盘空间。


1
Ext4具有更好的文件分配性能,因为可以一次分配最大100MB的整个块。
马丁

5
顺便说一下,“ truncate”命令会创建一个稀疏文件。例如,请参见en.wikipedia.org/wiki/Sparse_file
Jason Drew

2
人们似乎完全忽略了“稀疏文件将无法使用此功能”,其截断和dd搜索位于下面。
hpavc

1
您应该已经定义了“用于测试”的含义。测试硬盘的写入速度?测试df将报告什么?测试执行特定功能的应用程序。答案取决于您要测试的内容。无论如何,我有点晚了-我现在看到

1
以防万一,就像我一样,您正在寻找一种模拟完整分区的方法,别无所求/ dev / full
Julian

Answers:


508

dd其他答案是一个很好的解决方案,但为此目的它很慢。在Linux(和其他POSIX系统)中,我们可以fallocate使用所需的空间而无需实际写入,可以非常快地与大多数现代的基于磁盘的文件系统一起使用:

例如:

fallocate -l 10G gentoo_root.img

5
dd是否有可能已经在内部使用它了?如果我在3.0.0内核上执行“ dd if = / dev / zero of = zerofile bs = 1G count = 1”,则写入将在2秒内完成,写入数据速率超过每秒500兆字节。这显然是不可能的2.5"笔记本硬盘。
lxgr

21
fallocate正是我想要的。
2012年

7
此(fallocate)在Linux ZFS文件系统上也将不起作用-github.com/zfsonlinux/zfs/issues/326


3
在Debian中,GNU / Linux fallocate是该util-linux软件包的一部分。该工具是由RedHat的Karel Zak编写的,可在以下位置找到源代码:kernel.org/pub/linux/utils/util-linux
Franta

294

这是一个常见问题-尤其是在当今的虚拟环境中。不幸的是,答案并不像人们想象的那样简单。

dd是最明显的首选,但dd本质上是一个副本,它迫使您写入每个数据块(因此,初始化文件内容)...而且初始化是占用大量I / O时间的方法。(想让它花费更长的时间吗?使用/ dev / random而不是/ dev / zero!然后您将使用CPU和I / O时间!)最后,dd是一个不好的选择(尽管本质上是dd VM“创建” GUI使用的默认值)。例如:

dd if=/dev/zero of=./gentoo_root.img bs=4k iflag=fullblock,count_bytes count=10G

截断是另一种选择-可能是最快的...但这是因为它会创建“稀疏文件”。本质上,一个稀疏文件是磁盘上具有许多相同数据的部分,而底层文件系统实际上并没有真正存储所有数据,而是“假装”所有数据都在“欺骗”。因此,当您使用truncate为VM创建20 GB的驱动器时,文件系统实际上并没有分配20 GB,但是它作弊并说那里有20 GB的零,即使磁盘上只有一个磁道可能实际上(确实)正在使用。例如:

 truncate -s 10G gentoo_root.img

fallocate是最后-和最佳 - 选择与VM磁盘分配使用,因为它基本上是“储备”(或“分配”所有的空间你正在寻找的,但它并没有刻意去写东西所以。当您使用fallocate创建20 GB虚拟驱动器空间时,您确实会得到20 GB文件(而不是“稀疏文件”),并且您也不必费心向其中写入任何内容-这意味着实际上任何内容都可以包含在其中。那里-有点像全新的磁盘!)例如:

fallocate -l 10G gentoo_root.img

4
+1 truncate在JFS上起作用;fallocate, 没那么多。一点:数字中不能包含小数,我需要指定1536G,而不是1.5T
Calrion 2014年

1
根据我的fallocate手册页,这是只支持btrfsext4ocfs2,和xfs文件系统
弥敦道S.沃森-黑格

注意,swapon不幸的是,最后我检查了一下。在XFS邮件列表上进行了一些讨论,其中涉及使用fallocate选项来公开旧的自由空间数据,并且没有将范围标记为预分配,因此swapon将起作用。但是我认为什么也没做。
彼得·科德斯

1
仅供参考,尝试从中读取过多的数据/dev/random可能会导致随机数据用尽,并且“当熵池为空时,从/ dev / random进行的读取将阻塞,直到收集到其他环境噪声为止”,因此可能需要非常非常非常很长时间
Xen2050 '17

154

Linux和所有文件系统

xfs_mkfile 10240m 10Gigfile

Linux和某些文件系统(ext4,xfs,btrfs和ocfs2)

fallocate -l 10G 10Gigfile

OS X,Solaris,SunOS以及其他可能的UNIX

mkfile 10240m 10Gigfile

HP-UX

prealloc 10Gigfile 10737418240

说明

尝试使用mkfile <size>myfile作为替代dd。使用该-n选项时,会注明大小,但是直到将数据写入磁盘块时才分配磁盘块。如果没有该-n选项,则该空间将填充为零,这意味着要写入磁盘,这意味着要花费时间。

mkfile派生自SunOS,并非到处都有。大多数Linux系统具有xfs_mkfile完全相同的工作方式,尽管有名称,但不仅仅是在XFS文件系统上。它包含在xfsprogs(用于Debian / Ubuntu)或类似的命名软件包中。

大多数Linux系统还具有fallocate,它仅可在某些文件系统(例如btrfs,ext4,ocfs2和xfs)上工作,但速度最快,因为它会分配所有文件空间(创建非有孔文件),但不会初始化任何文件空间它的。


5
陌生人,您说的这个mkfile在哪里?它不在默认的RHEL安装中。
paxdiablo

2
这是solaris实用程序。如果您搜索gpl mkfile,则会找到一些源代码示例。
Martin Beckett

5
在OS X上可作为魅力:mkfile 1g DELETE_IF_LOW_ON_SSD_SPACE.img
Volker Rose

2
xfs_mkfile包含在Ubuntu的xfsprogs中,在我的ext3 fs上就像一个护身符。:)
格雷格·杜比奇

97
truncate -s 10M output.file

会立即创建一个10 M文件(M代表1024 * 1024字节,MB代表1000 * 1000-与K,KB,G,GB ...相同)

编辑:正如许多人指出的那样,这不会在设备上实际分配文件。这样,您实际上可以创建一个任意的大文件,而不管设备上的可用空间如何,因为它会创建一个“稀疏”文件。

因此,这样做时,您将推迟物理分配,直到访问文件为止。如果将此文件映射到内存,则可能无法达到预期的性能。

但这仍然是一个有用的命令


1
尝试过此操作,但它不会影响可用磁盘空间。必须,因为它是如前所述的稀疏文件。
Gringo Suave

7
这不应该是最主要的答案,因为它不能解决问题,fallocate下面的答案可以。
Gringo Suave

4
@GringoSuave,但这对于某些可能有类似但略有不同的问题的人仍然有用。
AJMansfield

@GringoSuave:似乎按照要求创建了一个大文件,为什么它不能解决问题?在谬误答案下也有注释,指出在大多数情况下它甚至都无法工作。
PavelŠimerda2014年

1
当他说这行不通时,为什么建议制作稀疏文件?
hpavc

44

搜寻是您想要的文件大小,以字节为单位-1。

dd if=/dev/zero of=filename bs=1 count=1 seek=1048575

6
我喜欢这种方法,但是评论者出于某种原因不希望使用稀疏文件。:(
短暂的

3
dd if = / dev / zero of = 1GBfile bs = 1000 count = 1000000
Damien 2010年

7
dd if = / dev / zero of = 01GBfile bs = 1024 count = $(((1024 * 1024)))
Xavier Decoret 2011年

1
对于稀疏文件,truncate似乎要好得多。
PavelŠimerda2014年

36

示例,其中seek是您想要的文件大小(以字节为单位)

#kilobytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200K

#megabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200M

#gigabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200G

#terabytes
dd if=/dev/zero of=filename bs=1 count=0 seek=200T


从dd联机帮助页中:

块和字节后面可以跟以下乘法后缀:c = 1,w = 2,b = 512,kB = 1000,K = 1024,MB = 1000 * 1000,M = 1024 * 1024,GB = 1000 * 1000 * 1000,G = 1024 * 1024 * 1024,依此类推,对于T,P,E,Z,Y。


这看起来比n-1方法好得多,因此基本上等效于truncate
PavelŠimerda2014年

18

我对Linux并不了解很多,但是这里有很多年前我写的C代码,用于伪造DC Share上的大文件。

#include < stdio.h >
#include < stdlib.h >

int main() {
    int i;
    FILE *fp;

    fp=fopen("bigfakefile.txt","w");

    for(i=0;i<(1024*1024);i++) {
        fseek(fp,(1024*1024),SEEK_CUR);
        fprintf(fp,"C");
    }
}

C中必须有更好的方法。您还需要关闭文件。迭代到一百万写一次1个字符...
ACV

18

制作1 GB的文件:

dd if=/dev/zero of=filename bs=1G count=1

7
我相信计数必须为1。(以centos测试)
SvennD

dd if=/dev/zero of=filename bs=20G count=1只会创建2GB的文件!不是20GB。
Maulik Gangani

9

您也可以使用“是”命令。语法非常简单:

#yes >> myfile

按“ Ctrl + C”停止此操作,否则它将耗尽您的所有可用空间。

要清理此文件,请运行:

#>myfile

将清除此文件。


6

我认为您不会比dd快得多。瓶颈是磁盘。无论您如何写,都要写入数百GB的数据。

但是,这可能适用于您的应用程序。如果您不关心文件的内容,那么如何创建一个内容为程序动态输出的“虚拟”文件呢?不用open()打开文件,而是使用popen()打开到外部程序的管道。外部程序会在需要时生成数据。管道打开后,它的行为就像常规文件一样,打开管道的程序可以是fseek(),rewind()等。当您打开管道时,需要使用pclose()而不是close()用管道完成。

如果您的应用程序需要将文件设置为一定大小,则由外部程序来确定“文件”在其中的位置,并在到达“末尾”时发送eof。


4

一种方法:如果可以确保不相关的应用程序不会以冲突的方式使用文件,则只需在特定目录中创建大小不同的文件池,然后在需要时创建指向它们的链接。

例如,有一个名为以下文件的池:

  • / home / bigfiles / 512M-A
  • / home / bigfiles / 512M-B
  • / home / bigfiles / 1024M-A
  • / home / bigfiles / 1024M-B

然后,如果您的应用程序需要一个名为/ home / oracle / logfile的1G文件,请执行“ln /home/bigfiles/1024M-A /home/oracle/logfile ”。

如果在单独的文件系统上,则必须使用符号链接。

A / B / etc文件可用于确保不相关的应用程序之间没有冲突的使用。

链接操作的速度尽可能快。


您可以选择一个小型泳池或大型泳池。无论如何,您至少需要一个文件,因为这是发问人的要求。如果池由一个文件组成,则不会丢失任何内容。如果您有大量的磁盘(并且应该以低廉的价格购买),那就没有问题了。
paxdiablo

3

GPL mkfile只是dd周围的(ba)sh脚本包装;BSD的mkfile只是存储一个非零的缓冲区,然后重复写入。我不希望前者的表现优于dd。后者可能会稍微忽略dd if = / dev / zero,因为它会忽略读取,但是做得更好的任何事情可能只是创建一个稀疏文件。

如果没有系统调用实际上为文件分配空间而不写数据(Linux和BSD也缺少此功能,也许还有Solaris),则可以通过使用ftrunc(2)/ truncate(1)扩展文件来在性能上获得小幅提高达到所需大小后,将文件映射到内存,然后将非零数据写入每个磁盘块的第一个字节(使用fgetconf查找磁盘块的大小)。


4
BSD和Linux实际上已经贬义了(编辑:它现在是POSIX并且广泛可用)。
东武

3

无耻的插件:OTFFS提供了一个文件系统,该文件系统提供生成的内容的任意大文件(嗯,差不多。埃字节是当前限制)。它是仅限Linux的普通C语言,并且处于早期alpha版本。

https://github.com/s5k6/otffs


3

这是我可以执行的最快速度(不是很快),但有以下限制:

  • 大文件的目标是填充磁盘,因此不可压缩。
  • 使用ext3文件系统。(fallocate不可用)

这是要点...

// include stdlib.h, stdio.h, and stdint.h
int32_t buf[256]; // Block size.
for (int i = 0; i < 256; ++i)
{
    buf[i] = rand(); // random to be non-compressible.
}
FILE* file = fopen("/file/on/your/system", "wb");
int blocksToWrite = 1024 * 1024; // 1 GB
for (int i = 0; i < blocksToWrite; ++i)
{
   fwrite(buf, sizeof(int32_t), 256, file);
}

在我们的案例中,这是针对嵌入式linux系统的,虽然效果很好,但希望更快一些。

仅供参考,命令dd if=/dev/urandom of=outputfile bs=1024 count = XX太慢以至无法使用。

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.