如何在 Linux( Red Hat Linux )系统上快速创建大文件?
dd会完成这项工作,但是当您需要数百 GB 大小的文件进行测试时,从驱动器读取/dev/zero
和写入驱动器可能需要很长时间......如果您需要重复执行此操作,那么时间真的会加起来。
我不关心文件的内容,我只想快速创建它。如何才能做到这一点?
使用稀疏文件对此不起作用。我需要为文件分配磁盘空间。
如何在 Linux( Red Hat Linux )系统上快速创建大文件?
dd会完成这项工作,但是当您需要数百 GB 大小的文件进行测试时,从驱动器读取/dev/zero
和写入驱动器可能需要很长时间......如果您需要重复执行此操作,那么时间真的会加起来。
我不关心文件的内容,我只想快速创建它。如何才能做到这一点?
使用稀疏文件对此不起作用。我需要为文件分配磁盘空间。
dd
从其他答案来看是一个很好的解决方案,但为此目的它很慢。在 Linux(和其他 POSIX 系统)中,我们有fallocate
,它使用所需的空间而不必实际写入它,它适用于大多数现代基于磁盘的文件系统,速度非常快:
例如:
fallocate -l 10G gentoo_root.img
这是一个常见的问题——尤其是在当今的虚拟环境中。不幸的是,答案并不像人们想象的那样直截了当。
dd 显然是首选,但 dd 本质上是一个副本,它迫使您写入每个数据块(因此,初始化文件内容)......而初始化占用了如此多的 I/O 时间。(想让它花费更长的时间?使用/dev/random而不是/dev/zero!那么你将使用 CPU 以及 I/O 时间!)尽管如此,dd 是一个糟糕的选择(虽然本质上是VM“创建”GUI 使用的默认值)。例如:
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 的零,即使磁盘上只有一个轨道可能实际上(真的)正在使用。例如:
truncate -s 10G gentoo_root.img
fallocate 是用于 VM 磁盘分配的最终 - 也是最好的-选择,因为它本质上是“保留”(或“分配”您正在寻找的所有空间,但它不会费心写任何东西。所以,当您使用 fallocate 创建一个 20 GB 的虚拟驱动器空间时,您确实会得到一个 20 GB 的文件(不是“稀疏文件”,而且您不必费心向其中写入任何内容——这意味着几乎任何内容都可以在其中那里——有点像一个全新的磁盘!)例如:
fallocate -l 10G gentoo_root.img
xfs_mkfile 10240m 10Gigfile
fallocate -l 10G 10Gigfile
mkfile 10240m 10Gigfile
prealloc 10Gigfile 10737418240
尝试mkfile <size>
myfile 作为dd
. 使用该-n
选项会记录大小,但在将数据写入磁盘块之前不会分配磁盘块。没有该-n
选项,空间是零填充的,这意味着写入磁盘,这意味着需要时间。
mkfile源自 SunOS,并非随处可用。大多数 Linux 系统的xfs_mkfile
工作方式完全相同,而且不只是在 XFS 文件系统上,尽管名称如此。它包含在xfsprogs(用于 Debian/Ubuntu)或类似命名的软件包中。
大多数 Linux 系统也有fallocate
,它只适用于某些文件系统(如 btrfs、ext4、ocfs2 和 xfs),但速度最快,因为它分配了所有文件空间(创建非空洞文件)但不初始化任何文件其中。
truncate -s 10M output.file
将立即创建一个 10 M 的文件(M 代表 1024 1024 字节,MB 代表 1000 1000 - 与 K、KB、G、GB 相同......)
编辑:正如许多人指出的那样,这不会在您的设备上物理分配文件。有了这个,您实际上可以创建一个任意大文件,而不管设备上的可用空间如何,因为它会创建一个“稀疏”文件。
例如,请注意此命令不会占用 HDD 空间:
### BEFORE
$ df -h | grep lvm
/dev/mapper/lvm--raid0-lvm0
7.2T 6.6T 232G 97% /export/lvm-raid0
$ truncate -s 500M 500MB.file
### AFTER
$ df -h | grep lvm
/dev/mapper/lvm--raid0-lvm0
7.2T 6.6T 232G 97% /export/lvm-raid0
因此,这样做时,您将推迟物理分配,直到文件被访问。如果您将此文件映射到内存,您可能无法获得预期的性能。
但这仍然是一个有用的命令。例如,当使用文件对传输进行基准测试时,仍然会移动指定大小的文件。
$ rsync -aHAxvP --numeric-ids --delete --info=progress2 \
root@mulder.bub.lan:/export/lvm-raid0/500MB.file \
/export/raid1/
receiving incremental file list
500MB.file
524,288,000 100% 41.40MB/s 0:00:12 (xfr#1, to-chk=0/1)
sent 30 bytes received 524,352,082 bytes 38,840,897.19 bytes/sec
total size is 524,288,000 speedup is 1.00
其中 seek 是您想要的文件大小(以字节为单位) - 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。
要制作 1 GB 的文件:
dd if=/dev/zero of=filename bs=1G count=1
我对 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");
}
}
您也可以使用“是”命令。语法相当简单:
#yes >> myfile
按“Ctrl + C”停止此操作,否则它将占用您所有可用空间。
要清理此文件,请运行:
#>myfile
将清理此文件。
我认为您不会比dd快得多。瓶颈是磁盘;不管你怎么做,向它写入数百 GB 的数据都需要很长时间。
但这里有一种可能适用于您的应用程序。如果您不关心文件的内容,那么创建一个内容是程序动态输出的“虚拟”文件怎么样?代替 open() 文件,使用 popen() 打开到外部程序的管道。外部程序在需要时生成数据。一旦管道打开,它就像一个常规文件一样,打开管道的程序可以 fseek()、rewind() 等。你需要使用 pclose() 而不是 close()用管道完成。
如果您的应用程序需要文件具有一定的大小,则由外部程序来跟踪它在“文件”中的位置,并在到达“结束”时发送一个 eof。
一种方法:如果您可以保证不相关的应用程序不会以冲突的方式使用文件,只需在特定目录中创建一个不同大小的文件池,然后在需要时创建指向它们的链接。
例如,有一个名为的文件池:
然后,如果您的应用程序需要一个名为 /home/oracle/logfile 的 1G 文件,请执行“ ln /home/bigfiles/1024M-A /home/oracle/logfile
”。
如果它位于单独的文件系统上,则必须使用符号链接。
A/B/etc 文件可用于确保不相关的应用程序之间没有冲突使用。
链接操作的速度与您所能获得的一样快。
GPL mkfile 只是 dd 的 (ba)sh 脚本包装器;BSD 的 mkfile 只是 memset 一个非零的缓冲区并重复写入它。我不认为前者会胜过 dd。后者可能会略微超越 dd if=/dev/zero 因为它省略了读取,但任何明显更好的东西可能只是创建一个稀疏文件。
如果没有一个系统调用,它实际上为文件分配空间而不写入数据(Linux 和 BSD 缺少这个,可能 Solaris 也是如此),你可能会通过使用 ftrunc(2)/truncate(1) 来扩展文件,从而在性能上得到小幅提升到所需的大小,将文件 mmap 到内存中,然后将非零数据写入每个磁盘块的第一个字节(使用 fgetconf 查找磁盘块大小)。
这是我能做到的最快速度(速度不快),但有以下限制:
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
太慢以至于无法使用。
无耻插件:OTFFS 提供了一个文件系统,可提供任意大(嗯,几乎。Exabytes 是当前限制)文件的生成内容。它仅适用于 Linux,纯 C,并且处于早期 alpha 版本。
您可以使用https://github.com/flew-software/trash-dump 创建任意大小且包含随机数据的文件
这是安装垃圾转储后可以运行的命令(创建一个 1GB 文件)
$ trash-dump --filename="huge" --seed=1232 --noBytes=1000000000
顺便说一句,我创建了它