为什么BufReader有时不填充给定的缓冲区?

问题描述 投票:0回答:1

我希望此代码在每个循环中读取3个字节,并且不打印。

但是文件的每8000个字节左右,它只能读取两个字节

use std::error::Error;
use std::fs::File;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::prelude::*;
use std::path::Path;
use std::io::SeekFrom;
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个字节)

file rust buffer
1个回答
0
投票

默认缓冲区大小为8KB。参见docs for BufReader::new

8192字节不能被3整除,因此在每个缓冲区的末尾会得到几个尾随字节。

您可以使用with_capicity constructor将缓冲区大小设置为8KB以外的值。

© www.soinside.com 2019 - 2024. All rights reserved.