我最近创建了一个测试文件,因为我想玩一下 logrotate。我正在寻找一种解决方案来创建任意大小的文件。我发现这是我的解决方案:
dd if=/dev/zero of=/path bs=1M count=30 status=progress
我还发现了这个:
dd if=/dev/urandom of=/path bs=1M count=30 status=progress
第一个示例创建一个包含零的文件,第二个示例创建一个包含随机文本的文件。两个文件的大小相同,均为 30M。
谁能解释一下,为什么用随机文本创建这个文件比用零创建这个文件需要更长的时间?因为它们的数据大小相同......
提前致谢 :)
答案1
从输出中可以看出,这两种方法都非常快。但是,数据来源之间存在明显差异。
/dev/zero
是一个伪文件,它只是生成一个零流,这是一个相当简单的任务/dev/urandom
实际上访问内核的熵池来生成随机数,因此比简单地生成相同的固定值(如/dev/zero
.
/dev/urandom
这就是为什么从 读取永远不可能像从 读取一样快的原因/dev/zero
。如果您有兴趣,维基百科文章关于/dev/random
可以作为进一步阅读的起点。
答案2
您假设磁盘上的文件只是从输入设备输出的内容的逐字节副本。不一定是这样。
除了数据源(已在另一个答案中介绍)之外,性能上还存在另一个潜在差异 - 文件系统压缩、重复数据删除和稀疏文件的潜在创建。
如果您将一个只有零的文件写入压缩数据的文件系统,则此类文件系统所要做的就是不断更新所有这些零的“大小”。这可以非常快地完成,因为除了唯一的内容为零以及这些零的数量必须写入磁盘这一事实之外,没有任何信息。
真正的随机数据根本无法被压缩。
文件系统还可以“删除重复”块即使文件未压缩,尤其是 ZFS 等写时复制文件系统。在执行重复数据删除的文件系统上,只需将一个零块写入磁盘,然后只需添加对该块的引用。
随机数据非常非常不可能产生重复的块。
文件系统还可以检测到块的内容全为零并创建一个稀疏文件- 在哪里没有什么必须写入磁盘。
所有这些都比实际将所有零写入磁盘要快得多。