快速生成大量随机大小的文件
程序员文章站
2022-04-04 12:29:46
要生成大量随机大小的文件,最简单的方法是for循环N次。 例如,生成100W个0 16K大小的小文件(尝试时请改小一点数量,不然时间要很久): tmp_dir=/tmp/temp for i in {1..1000000};do dd if=/dev/zero of=$tmp_dir/${i}.lo ......
要生成大量随机大小的文件,最简单的方法是for循环n次。
例如,生成100w个0-16k大小的小文件(尝试时请改小一点数量,不然时间要很久):
tmp_dir=/tmp/temp for i in {1..1000000};do dd if=/dev/zero of=$tmp_dir/${i}.log bs=`shuf -n 1 -i 0-16`k count=1 &>/dev/null done
这里使用dd命令从/dev/zero中取数据填充小文件,其中tmp_dir变量是存放大量小文件的目录,文件的随机大小由shuf命令生成。
但是这样会非常的慢,不仅占用大量io,操作系统还繁忙地open、close文件描述符。这样的创建方式效率极低。
为了不频繁open、close文件描述符,可以直接将创建的文件放进压缩包中,比如cpio、tar(但不要加数据压缩功能,如zip、xz等,因为压缩会占用大量cpu进行计算),等给定数量的文件创建完后再解压这个压缩包。这种方式在shell中实现起来比较复杂。
更好的方式是使用split命令,它可以将文件按给定大小均匀切分成小文件。这里可以使用/dev/zero作为数据源。
因为split只能切分成等大小的文件,所以大小无法随机,只能在一定数量的循环下,多次切分成等随机大小的文件。正如下面的for和shuf。
tmp_dir=/tmp/temp for i in {1..100};do dd bs=10000 count=8192 if=/dev/zero |\ split -b `shuf -n 1 -i 1-16`k -a 5 -d - "$tmp_dir/$i-" done
每次循环中,dd每次生成8192*10000=8.2m的数据源,这8.2m的数据供split进行分割,分隔的每个文件都由shuf
确定,比如某次shuf的值为5,那么8.2m的数据全部切分成5k大小的文件共16000个小文件。这样的操作循环100次。
这样的方式非常快,但是只循环了100次,shuf的随机数分配不够均匀,所以无法控制文件的数量,比如上面的命令可能会生成200w个文件,如果运气差可能生成400w个文件。
改成下面的,循环次数增加一些,每次数据源大小小一点:
for i in {1..10000};do dd bs=100 count=8192 if=/dev/zero |\ split -b `shuf -n 1 -i 1-16`k -a 3 -d - "$i-" done
生成100w个文件大概需要5分钟(普通固态下)。同样的,文件数量不可控制。