Rust 是否具有与 Java 中的等效 Stream 类?

Does Rust have equivalent Stream classes like in Java?

我正在通过编写一个简单的 ZIP 处理程序来学习 Rust。它运作良好,我对此很满意。但是,我想 return 一个 Java 类似 Stream 的 extract_file() 功能。

目前我正在 returning 一个 Vec,这可以通过 STORE 和 DEFLATE 途径完成。 (没有压缩和压缩)。

但是,我无法为这两个选项找到 class 或我可以 return 的特征,因为我没有预读整个输入数据。

我正在寻找相当于 Java 的 IO 流:

Stream fileStream;
if (stored) {
  return fileStream;
} else if (deflate) {
  return DeflateStream(fileStream);
}

有什么指点吗?

更多std::io::Read and std::io::Write traits. They are implemented for files, TCP streams, and more. See std::io's docs

Rust 更喜欢使用 std::io::Read and std::io::Write traits for this. Additionally you will probably want to also add a requirement on std::io::Seek 这样您就可以在字节流中移动光标。

总体思路如下:

// Wrap around another Read type so we can use it as we parse
pub struct Deflater<R> {
    stream: R,
}

impl<R> Deflater<R> {
    pub fn new(stream: R) -> Self {
        Deflater { stream }
    }
}

// We provide our own Read implementation which can then refer to our inner Read type
impl<R: Read> Read for Deflater<R> {
    fn read(&mut self, buffer: &mut [u8]) -> io::Result<usize> {
        // Just defer to our inner read
        self.stream.read(buffer)
    }
}

对于您的示例,由于我们需要知道具体类型,因此我们有两种方法。我们可以为它创建一个枚举或将其用作匿名特征。

fn box_approach<'a, R: 'a + Read>(file_stream: R, stored: bool, deflate: bool) -> Box<dyn 'a + Read> {
    if stored {
        return Box::new(file_stream)
    } else if deflate {
        return Box::new(Deflater::new(file_stream))
    }
    
    panic!("Must be either stored or deflate!")
}

fn enum_approach<R>(file_stream: R, stored: bool, deflate: bool) -> HandleStream<R> {
    if stored {
        return HandleStream::Stored(file_stream)
    } else if deflate {
        return HandleStream::Deflate(Deflater::new(file_stream))
    }
    
    panic!("Must be either stored or deflate!")
}


enum HandleStream<R> {
    Stored(R),
    Deflate(Deflater<R>),
}

impl<R: Read> Read for HandleStream<R> {
    fn read(&mut self, buffer: &mut [u8]) -> io::Result<usize> {
        match self {
            HandleStream::Stored(stream) => stream.read(buffer),
            HandleStream::Deflate(deflater) => deflater.read(buffer),
        }
    }
}