Почему BufReader :: read не всегда полностью заполняет данный буфер? - PullRequest
3 голосов
/ 16 октября 2019

Я ожидал, что этот код будет читать 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(())
}

Скомпилировано на Mac с rustc problem.rs и запустить с ./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 байт за раз.

1 Ответ

2 голосов
/ 16 октября 2019

Размер буфера по умолчанию составляет 8 КБ. См. документы для BufReader::new.

8192 байта, которые не делятся на 3, поэтому вы получаете пару конечных байтов в конце каждого буфера.

Вы можете установить размер буфера, отличный от 8 КБ, используя конструктор with_capacity .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...