写文件为什么要 BufWriter?一个 writeln! 到底触发几次系统调用?stdout 默认是怎么缓冲的?丢数据的场景有哪些?这篇用写调用计数和 100 万行计时回答。
编译:成功
运行(退出码 0):
无缓冲 File:writeln! 10 万次 → 底层 write 调用 511110 次,共 1200000 字节
BufWriter(默认容量 8192):底层 write 调用 147 次,共 1200000 字节
LineWriter(每遇到换行就刷新):底层 write 调用 100000 次
BufWriter::with_capacity( 64):底层 write 调用 19902 次
BufWriter::with_capacity( 1024):底层 write 调用 1177 次
BufWriter::with_capacity(1048576):底层 write 调用 2 次读取侧见BufReader 与缓冲读取;文件基础见std::fs 文件读写。write 调用数是在 Rust 层统计的,不是内核系统调用计数。
编译:成功
运行(退出码 0):
无缓冲 File(10 万行实测折算到 100 万行): 8898.4 ms
BufWriter 默认容量: 30.9 ms
BufWriter 1 MiB 容量: 28.0 ms
先拼成 String 再一次 fs::write: 25.5 ms文件在系统缓存里(没有 fsync),耗时是本机 release 实测的最小值;无缓冲项为 10 万行折算到 100 万行。
编译:成功 println 写 20 万行到 /dev/null: 184.0 ms locked 写 20 万行到 /dev/null: 183.7 ms bufwriter 写 20 万行到 /dev/null: 11.9 ms
编译:成功 drop 写入 1000 行(共 12000 字节)后,文件大小 12000 字节 flush_then_exit 写入 1000 行(共 12000 字节)后,文件大小 12000 字节 exit 写入 1000 行(共 12000 字节)后,文件大小 8192 字节 forget 写入 1000 行(共 12000 字节)后,文件大小 8192 字节
drop 的规则见Drop Trait 与资源释放;文件描述符的释放见文件描述符与资源释放。