为什么 BufReader::read 并不总是完全填满给定的缓冲区?
Why does BufReader::read not always completely fill the given buffer?
我希望这段代码在每个循环中读取 3 个字节而不打印,但是文件的每 8000 个字节左右,它只读取两个字节:
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::SeekFrom;
use std::path::Path;
fn main() -> std::io::Result<()> {
let sequence: [u8; 3] = [1, 2, 3];
let file_path = Path::new("./test_file");
//fill a file with 1,2,3,1,2,3...
{
let mut output_file: std::io::BufWriter<std::fs::File>;
output_file = BufWriter::new(File::create(file_path)?);
for _i in 0..100000 {
match output_file.write(&sequence) {
Err(why) => panic!("could not write {}", Error::description(&why)),
Ok(_) => {}
}
}
}
//read the file 3 bytes at a time
{
let mut input_file: std::io::BufReader<std::fs::File>;
input_file = BufReader::new(File::open(file_path)?);
for i in 0..100000 {
let mut raw = [0; 3];
let result = match input_file.read(&mut raw) {
Err(why) => panic!("could not read {}", Error::description(&why)),
Ok(x) => x,
};
// print if something other than 3 bytes were read
if result != 3 {
println!(
"file pos {}, data read {}, buffer = [{},{},{}]",
i * 3,
result,
raw[0],
raw[1],
raw[2]
);
}
}
}
Ok(())
}
使用 rustc problem.rs
在 Mac 上编译,使用 ./problem
在 运行 上编译。
输出:
file pos 8190, data read 2, buffer = [1,2,0]
file pos 16383, data read 2, buffer = [3,1,0]
file pos 24576, data read 2, buffer = [2,3,0]
file pos 32769, data read 2, buffer = [1,2,0]
file pos 40962, data read 2, buffer = [3,1,0]
file pos 49155, data read 2, buffer = [2,3,0]
file pos 57348, data read 2, buffer = [1,2,0]
file pos 65541, data read 2, buffer = [3,1,0]
...
这似乎表明与内部 8192 大小的缓冲区有关。
为什么我每次都得不到3个字节?我得到了一次读取 5 个字节的类似结果。
默认缓冲区大小为 8KB。参见 docs for BufReader::new
.
8192 字节不能被 3 整除,因此每个缓冲区的末尾都有几个尾随字节。
您可以使用 with_capacity
constructor.
将缓冲区大小设置为 8KB 以外的值
我希望这段代码在每个循环中读取 3 个字节而不打印,但是文件的每 8000 个字节左右,它只读取两个字节:
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::SeekFrom;
use std::path::Path;
fn main() -> std::io::Result<()> {
let sequence: [u8; 3] = [1, 2, 3];
let file_path = Path::new("./test_file");
//fill a file with 1,2,3,1,2,3...
{
let mut output_file: std::io::BufWriter<std::fs::File>;
output_file = BufWriter::new(File::create(file_path)?);
for _i in 0..100000 {
match output_file.write(&sequence) {
Err(why) => panic!("could not write {}", Error::description(&why)),
Ok(_) => {}
}
}
}
//read the file 3 bytes at a time
{
let mut input_file: std::io::BufReader<std::fs::File>;
input_file = BufReader::new(File::open(file_path)?);
for i in 0..100000 {
let mut raw = [0; 3];
let result = match input_file.read(&mut raw) {
Err(why) => panic!("could not read {}", Error::description(&why)),
Ok(x) => x,
};
// print if something other than 3 bytes were read
if result != 3 {
println!(
"file pos {}, data read {}, buffer = [{},{},{}]",
i * 3,
result,
raw[0],
raw[1],
raw[2]
);
}
}
}
Ok(())
}
使用 rustc problem.rs
在 Mac 上编译,使用 ./problem
在 运行 上编译。
输出:
file pos 8190, data read 2, buffer = [1,2,0]
file pos 16383, data read 2, buffer = [3,1,0]
file pos 24576, data read 2, buffer = [2,3,0]
file pos 32769, data read 2, buffer = [1,2,0]
file pos 40962, data read 2, buffer = [3,1,0]
file pos 49155, data read 2, buffer = [2,3,0]
file pos 57348, data read 2, buffer = [1,2,0]
file pos 65541, data read 2, buffer = [3,1,0]
...
这似乎表明与内部 8192 大小的缓冲区有关。
为什么我每次都得不到3个字节?我得到了一次读取 5 个字节的类似结果。
默认缓冲区大小为 8KB。参见 docs for BufReader::new
.
8192 字节不能被 3 整除,因此每个缓冲区的末尾都有几个尾随字节。
您可以使用 with_capacity
constructor.