c++怎么快速生成一个随机填充内容的测试大文件_rand与write结合【附代码】

千雪吖_8088

千雪吖_8088

2026-03-25

261人浏览

原创

应避免用 std::rand + write 生成大文件,因其随机性差、系统调用多、多线程不安全;推荐用 std::random_device + std::mt19937_64 + std::uniform_int_distribution 批量填充缓冲区后 write,或直接读 /dev/urandom(Linux/macOS),超大文件需先 fallocate 预分配。

c++怎么快速生成一个随机填充内容的测试大文件_rand与write结合【附代码】

用 std::rand 配合 write 生成大文件,速度不快反而容易翻车

直接用 std::rand + write 循环填充,看似简单,实际在 Linux/macOS 下常卡在系统调用开销上,Windows 下还可能因 rand 实现低效拖慢整条流水线。更关键的是:std::rand 默认周期短、低位重复性强,生成的“随机”字节在统计意义上并不均匀——尤其当你要测存储、压缩或加密模块时,这种偏差会掩盖真实问题。

  • 别用 srand(time(nullptr)) 初始化一次就完事:多线程下未加锁会崩,单线程下也只影响低位,rand() % 256 生成的字节分布明显偏斜
  • 避免每字节调用一次 rand():1GB 文件调用 10⁹ 次函数,光栈帧进出就吃掉可观时间
  • write 不带缓冲地小块写入(比如每次 1 字节)会触发大量系统调用,实测比批量写慢 2–3 个数量级

改用 std::random_device + std::uniform_int_distribution 批量预生成

真正快且靠谱的做法是:先用高质量熵源初始化生成器,再批量产出固定大小的缓冲区(如 64KB),最后用 write 一次性刷出。这样既避开 rand 的缺陷,又压低系统调用频次。

  • std::random_device 在多数现代系统上对接硬件 RNG 或内核熵池,比 time() 种子强得多
  • 用 std::uniform_int_distribution 直接生成字节数组,避免 % 运算引入偏差
  • 缓冲区大小设为 4KB–64KB:太小起不到批处理作用,太大可能触发 malloc 延迟或内存碎片
#include <random>
#include <unistd.h>
#include <fcntl.h><p>int fd = open("test.bin", O_WRONLY | O_CREAT, 0644);
std::random_device rd;
std::mt19937_64 gen(rd());
std::uniform_int_distribution<uint8_t> dist;</uint8_t></p>
<p>const size_t buf_size = 65536;
std::vector<uint8_t> buf(buf_size);
for (size_t written = 0; written </uint8_t></p></fcntl.h></unistd.h></random>

绕过 C++ 标准库,用 /dev/urandom 直读(Linux/macOS)

如果只要“够用的随机性”,且目标平台确定支持 /dev/urandom,这是最简最快路径——内核已做好缓冲与批处理,用户态几乎零计算开销。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 打开 /dev/urandom 后反复 read,比自己生成快 3–5 倍(实测 1GB 耗时从 1.8s 降到 0.4s)
  • 注意 read 可能返回少于请求长度,必须循环直到填满缓冲区
  • Windows 上不可用,得 fallback 到 CryptGenRandom 或 BCryptGenRandom,接口差异大,别硬套
int urand_fd = open("/dev/urandom", O_RDONLY);
ssize_t total = 0;
while (total <h3>生成超大文件(>10GB)时,<code>fallocate</code> 预分配再覆写更稳</h3><p>直接 <code>write</code> 写 20GB,遇到机械盘或某些文件系统(如 ext3)可能因元数据更新阻塞,甚至中途 <code>ENOSPC</code>。先 <code>fallocate</code> 划出空间,再随机覆写,既能保大小精确,又能规避碎片和延迟突刺。</p>
  • fallocate(fd, 0, 0, size) 在支持的文件系统上是纯元数据操作,毫秒级完成
  • 之后仍要用上面任一方式往里填内容,fallocate 不等于“已写入”,只是预留了磁盘块
  • macOS 用 ftruncate + posix_fallocate 替代,后者在 HFS+ 上可能失败,得降级处理

生成大文件这事,核心不是“怎么填随机数”,而是“别让随机性拖慢 I/O,也别让 I/O 掩盖随机性缺陷”。越往后做性能压测或模糊测试,越要盯住这两头的细节——比如 std::mt19937_64 的状态大小、/dev/urandom 的读取边界、甚至 write 返回值是否真等于请求长度。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3188

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

5069

12

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.12.29

3829

9

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

2026.01.19

466

15

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

6187

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2608

6

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

4418

6

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

2025.12.24

1229

20

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

2026.01.21

423

30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习