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

时间:2008-11-03 03:08:03

标签: linux file filesystems

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

dd将完成这项工作,但是当您需要一个数百GB的文件进行测试时,从/dev/zero读取并写入驱动器可能需要很长时间...如果您需要反复这样做,时间真的加起来。

我不关心文件的内容,我只是想快速创建它。怎么办呢?

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

14 个答案:

答案 0 :(得分:447)

来自其他答案的

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

例如:

fallocate -l 10G gentoo_root.img

答案 1 :(得分:277)

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

dd是明显的第一选择,但是dd本质上是一个副本,它会强制你编写每个数据块(因此,初始化文件内容)......而初始化是占用这么多I / O时间的东西。 (想要花更长的时间吗?使用/dev/random代替/dev/zero!然后你将使用CPU以及I / O时间!)最后,dd是一个糟糕的选择(虽然本质上是VM“创建”GUI使用的默认值。 E.g:

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

truncate是另一种选择 - 而且可能是最快的......但那是因为它创建了一个“稀疏文件”。本质上,稀疏文件是具有大量相同数据的磁盘的一部分,并且底层文件系统通过不真正存储所有数据来“欺骗”,而只是“假装”它就在那里。因此,当您使用truncate为您的VM创建一个20 GB的驱动器时,文件系统实际上并没有分配20 GB,但它会欺骗并说有20 GB的零,即使磁盘上只有一个磁道实际上(真的)可能正在使用中。 E.g:

 truncate -s 10G gentoo_root.img
用于VM磁盘分配的

fallocate是最终 - 和最佳 - 选择,因为它基本上是“保留”(或“分配”你正在寻找的所有空间,但它并不打算写任何东西。所以,当你使用fallocate创建一个20 GB的虚拟驱动器空间时,你确实得到一个20 GB的文件(不是“稀疏”文件“,你不会费心写任何东西 - 这意味着几乎任何东西都可以在那里 - 有点像一个全新的磁盘!”例如:

fallocate -l 10G gentoo_root.img

答案 2 :(得分:136)

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),但速度最快,因为它分配了所有文件空间(非多孔的文件)但不会初始化任何文件。

答案 3 :(得分:92)

truncate -s 10M output.file

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

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

因此,在执行此操作时,您将推迟物理分配,直到访问该文件。如果要将此文件映射到内存,则可能没有预期的性能。

但这仍然是一个了解

的有用命令

答案 4 :(得分:42)

其中seek是您想要的文件大小 - 以字节为单位 - 。

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

答案 5 :(得分:34)

其中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。

答案 6 :(得分:16)

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

答案 7 :(得分:14)

制作1 GB文件:

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

答案 8 :(得分:8)

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

#yes >> myfile

按“Ctrl + C”停止此操作,否则会占用所有可用空间。

要清理此文件,请运行:

#>myfile

将清理此文件。

答案 9 :(得分:5)

我认为你不会比dd快得多。瓶颈是磁盘;无论你怎么做,写入数百GB的数据都需要很长时间。

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

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

答案 10 :(得分:3)

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

例如,有一个名为:

的文件池
  • /家庭/ 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文件可用于确保不相关的应用程序之间没有冲突的使用。

链接操作的速度与您的速度一样快。

答案 11 :(得分:2)

GPL mkfile只是围绕dd的(ba)sh脚本包装器; BSD的mkfile只是存储一个非零的缓冲区并重复写入。我不希望前者超过dd。后者可能略微超出dd if = / dev / zero,因为它省略了读取,但任何做得更好的东西可能只是创建一个稀疏文件。

如果系统调用实际上没有写入数据就为文件分配空间(Linux和BSD也没有这个,也可能是Solaris),你可以通过使用ftrunc(2)/ truncate(1)来获得性能的小改进将文件扩展到所需的大小,将文件mmap到内存中,然后将非零数据写入每个磁盘块的第一个字节(使用fgetconf查找磁盘块大小)。

答案 12 :(得分:2)

无耻插件:OTFFS提供了一个文件系统,可以提供生成内容的任意大(好,几乎是Exabytes是当前限制)文件。它只有Linux,普通的C和早期的alpha。

请参阅https://github.com/s5k6/otffs

答案 13 :(得分:1)

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

  • 大文件的目标是填充磁盘,因此无法压缩。
  • 使用ext3文件系统。 (没有来自分居)

这是它的要点...... `

// 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系统的,这种方法效果很好,但更喜欢更快的东西。

FYI命令&#34; dd if = / dev / urandom of = outputfile bs = 1024 count = XX&#34;很慢,无法使用。