在Linux系统上快速创build一个大文件?

如何快速在Linux( Red Hat Linux )系统上创build大文件? dd会完成这个工作,但是当你需要一个文件大小为几百GB的文件进行testing时,读取/dev/zero并写入驱动器可能需要很长时间…如果你需要重复这个操作,加起来。

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

使用稀疏文件不适用于此。 我需要给文件分配磁盘空间。

dd是一个很好的解决scheme,但是这个目的很慢。 在Linux中,我们已经fallocate

例如:

 fallocate -l 10G gentoo_root.img 

这是一个常见的问题 – 特别是在当今虚拟环境中。 不幸的是,答案并不像人们假设的那样直截了当。

dd是明显的第一select,但dd本质上是一个副本,并迫使你写每一块数据(因此,初始化文件内容)…而这种初始化是占用这么多的I / O时间。 (想要使它更长时间?使用/ dev / random而不是/ dev / zero !那么你将使用CPU以及I / O时间!)最后,尽pipedd是一个糟糕的select默认由VM“创build”GUI使用)。 例如:

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

截断是另一种select – 可能是最快的…但这是因为它创build了一个“稀疏文件”。 从本质上讲,稀疏文件是一个磁盘部分,有很多相同的数据,底层的文件系统并不真正存储所有的数据,而只是“假装”它在那里。 因此,当你使用截断为你的虚拟机创build一个20GB的驱动器时,文件系统实际上并没有分配20GB,但是它作弊并且说有20GB的零,即使只有一个磁道可能实际上(真的)在使用中。 例如:

  truncate -s 10G gentoo_root.img 

fallocate是 VM磁盘分配最后一个select ,因为它基本上“保留”(或“分配”你寻求的所有空间,但是它不会写任何东西,所以,当你使用fallocate来创build一个20GB的虚拟磁盘空间时,你确实得到了一个20GB的文件(不是一个“稀疏文件”),你不会为它写任何东西 – 这意味着几乎任何东西都可以有 – 就像一个全新的磁盘!)例如:

 fallocate -l 10G gentoo_root.img 

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选项logging大小,但在写入数据之前不会分配磁盘块。 如果没有-n选项,空间是零填充的,这意味着写入磁盘,这意味着需要时间。

mkfile是从SunOS衍生出来的,并且在任何地方都不可用。 大多数Linux系统的xfs_mkfile工作方式完全相同,而不仅仅是在XFS文件系统上。 它包含在xfsprogs (用于Debian / Ubuntu)或类似的命名包中。

大多数Linux系统也有fallocate ,它只适用于某些文件系统(如btrfs,ext4,ocfs2和xfs),但速度最快,因为它分配所有文件空间(创build非多孔文件),但不初始化任何一个。

 truncate -s 10M output.file 

将立即创build一个10 M文件(M代表1024 * 1024字节,MB代表1000 * 1000 – 与K,KB,G,GB相同)

编辑:正如很多人指出的,这将不会物理分配您的设备上的文件。 有了这个,你实际上可以创build一个任意的大文件,而不pipe设备上的可用空间

所以,这样做的时候,你将会推迟物理分配,直到文件被访问。 如果您将此文件映射到内存,则可能没有预期的性能。

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

在哪里寻找是你想要的文件的大小以字节为单位 – 1。

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

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的手册:

BLOCKS和BYTES后面跟有以下乘法后缀: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等。

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

 #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"); } } 

制作一个1G文件:

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

你也可以使用“是”命令。 语法相当简单:

 #yes >> myfile 

按“Ctrl + C”停止这个,否则它会吃掉所有可用的空间。

清理这个文件运行:

 #>myfile 

将清理这个文件。

我不认为你会比dd快得多。 瓶颈是磁盘; 写数百GB的数据将花费很长时间,不pipe你怎么做。

但是这有可能适用于您的应用程序。 如果你不关心文件的内容,那么如何创build一个“虚拟”文件,其内容是程序的dynamic输出? 而不是打开()该文件,使用popen()打开一个pipe道到外部程序。 外部程序在需要时生成数据。 一旦pipe道打开,它就像一个普通的文件一样,打开pipe道的程序可以fseek(),rewind()等等。当你需要使用pclose()而不是close()用pipe子完成。

如果您的应用程序需要该文件具有一定的大小,则将由外部程序来跟踪“文件”中的位置,并在达到“结束”时发送一个eof。

一种方法:如果您可以保证不相关的应用程序不会以冲突的方式使用这些文件,只需在特定目录中创build不同大小的文件池,然后在需要时创build链接。

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

  • /家庭/ bigfiles / 512M-A
  • /家庭/ bigfiles / 512M-B
  • /家庭/ bigfiles / 1024M-A
  • /家庭/ bigfiles / 1024M-B

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

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

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

链接操作的速度和您所能获得的一样快。

GPL mkfile仅仅是一个(ba)sh脚本包装器; BSD的mkfile只是memsets一个非零的缓冲区并重复写入。 我不希望前者超出dd。 后者可能由于省略了读取而稍微偏离了dd,因为它稍微有些偏差,但是任何明显更好的东西可能只是创build一个稀疏文件。

如果没有一个系统调用为文件实际分配空间而不写数据(而Linux和BSD缺less这个,可能还有Solaris),使用ftrunc(2)/ truncate(1)来扩展文件将文件映射到内存中,然后将非零数据写入每个磁盘块的第一个字节(使用fgetconf查找磁盘块大小)。

这是我能做的最快的(这不是快),有以下限制:

  • 大文件的目标是填充磁盘,所以不能被压缩。
  • 使用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); } 

`

在我们的情况下,这是一个embedded式Linux系统,这工作得不错,但宁愿更快。

FYI命令“dd if = / dev / urandom of = outputfile bs = 1024 count = XX”是如此之慢以至于无法使用。