快速生成大量随机大小的文件

要生成大量随机大小的文件,最简单的方法就是for循环N次。

例如生成100万个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
完毕

这里使用dd命令将/dev/zero中的数据填充到小文件中。 tmp_dir变量是存储大量小文件的目录。文件的随机大小由 shuf 命令生成。

但这会非常慢。不仅占用大量IO,操作系统还忙于打开和关闭文件描述符。这种创建方式效率极低。

为了不频繁打开和关闭文件描述符,可以直接将创建的文件放入压缩包中,如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 计数=8192 if=/dev/0 |\
    split -b `shuf -n 1 -i 1-16`k -a 5 -d - "$tmp_dir/$i-"
完毕

每个周期dd每次生成8192*10000=8.2M的数据源。这8.2M数据是通过split来划分的。每个分离的文件由shuf决定,比如a的shuf值为5,那么8.2M的数据被分成5k大小的文件,总共16000个小文件。该操作重复100次。

这个方法速度很快,但是只循环100次。 shuf的随机数分布不够均匀,因此无法控制文件数量。例如,上面的命令可能会生成200万个文件,如果运气不好的话,可能会生成400万个文件。 。

改为如下,增加循环次数,每次数据源大小变小:

for i in {1..10000};do
    dd bs=100 计数=8192 if=/dev/0 |\
    分割 -b `shuf -n 1 -i 1-16`k -a 3 -d - "$i-"
完毕

生成100万个文件大约需要5分钟(普通固态下)。同样,文件的数量也是不可控的。

相关文章