Rust Streaming Pipeline

u59ebvdq  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(74)

我发现Rust流文档令人费解,并且不存在示例。
尝试创建代码示例可能比概述问题更令人困惑。
给定一个要传递给消费函数的读流,我想向流管道引入一个中间步骤,它可以计算字节数,但可以做任何事情,开销最小。
第一个月
示例流水线:
首先获取文件流,然后对流执行转换,最后流到磁盘(新文件)。

ubof19bj

ubof19bj1#

我已经实现了Read适配器,它应该是零成本的抽象,以实现您引入“中间步骤”的目的。
它类似于Iterator::map,但用于Read示例。

  • (我假设Read示例就是所谓的流。你似乎在使用Java/C++的术语。如果你有其他的意思,请澄清。
use std::io::{Read, Write};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // It's your “read stream”. Could be any.
    let reader = std::fs::OpenOptions::new().read(true).open("in_file.txt")?;
    // It's your adaptor to perform “middle step”.
    let mut trans_reader = TransReader {
        orginal: reader,
        transform: |bytes: &mut [u8]| {
            // Could be any transformation.
            bytes.make_ascii_uppercase();
        },
    };
    // It's your “write stream”. Could be any.
    let mut writer = std::fs::OpenOptions::new()
        .create(true)
        .truncate(true)
        .write(true)
        .open("out_file.txt")?;

    // You can read bytes in anyway you want and then write. Eg. read all then write all.
    let mut buf = vec![];
    trans_reader.read_to_end(&mut buf)?;
    writer.write_all(&buf)?;

    Ok(())
}

// It's my implementation of adaptor you need.
pub struct TransReader<R: Read, F: FnMut(&mut [u8])> {
    pub orginal: R,
    pub transform: F,
}
impl<Org: Read, F: FnMut(&mut [u8])> Read for TransReader<Org, F> {
    // This is the only method that needs to be implemented.
    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
        let res = self.orginal.read(buf);
        if let Ok(written_count) = res {
            (self.transform)(&mut buf[..written_count]);
        }
        res
    }
    // I'm not 100% if manual impl. of other methods would also make for performance.
}

字符串

相关问题