如何创建可以用作读者,作家或在Rust中寻找的内存对象



我需要一个完全内存的对象,我可以将其提供给BufReaderBufWriter。类似于Python的StringIO。我想使用Files。

通常使用的对象写入并从这样的对象中读取并阅读。

有没有一种方法使用标准库?

实际上有一种方法: Cursor<T>
也请阅读Shepmaster的答案,说明为什么通常更容易

在文档中,您可以看到以下内容:

impl<T> Seek for Cursor<T> where T: AsRef<[u8]>
impl<T> Read for Cursor<T> where T: AsRef<[u8]>
impl Write for Cursor<Vec<u8>>
impl<T> AsRef<[T]> for Vec<T>

从中您可以看到您可以将Cursor<Vec<u8>>类型使用作为普通文件,因为该类型已实现ReadWriteSeek

小示例( Playground ):

use std::io::{Cursor, Read, Seek, SeekFrom, Write};
// Create fake "file"
let mut c = Cursor::new(Vec::new());
// Write into the "file" and seek to the beginning
c.write_all(&[1, 2, 3, 4, 5]).unwrap();
c.seek(SeekFrom::Start(0)).unwrap();
// Read the "file's" contents into a vector
let mut out = Vec::new();
c.read_to_end(&mut out).unwrap();
println!("{:?}", out);

有关更有用的示例,请检查上面链接的文档。

您不需要Cursor 大多数时候

我可以给BufReaderBufWriter

的对象

BufReader需要一个实现Read的值:

impl<R: Read> BufReader<R> {
    pub fn new(inner: R) -> BufReader<R>
}

BufWriter需要一个实现Write的值:

impl<W: Write> BufWriter<W> {
    pub fn new(inner: W) -> BufWriter<W> {}
}

如果您查看了Read的实施者,您将找到impl<'a> Read for &'a [u8]

如果您查看了Write的实施者,则会找到impl Write for Vec<u8>

use std::io::{Read, Write};
fn main() {
    // Create fake "file"
    let mut file = Vec::new();
    // Write into the "file"
    file.write_all(&[1, 2, 3, 4, 5]).unwrap();
    // Read the "file's" contents into a new vector
    let mut out = Vec::new();
    let mut c = file.as_slice();
    c.read_to_end(&mut out).unwrap();
    println!("{:?}", out);
}

写信给Vec总是会附加到最后。我们还可以将切片切成可以更新的Vecc的每个读取都会越来越进一步推进切片,直到其为空。

Cursor的主要区别:

  • 无法寻求数据,因此您无法轻易重新阅读数据
  • 除了结束以外的任何地方都不能写信

如果要使用内存String使用BufReader,则可以使用as_bytes()方法:

use std::io::BufRead;
use std::io::BufReader;
use std::io::Read;
fn read_buff<R: Read>(mut buffer: BufReader<R>) {
    let mut data = String::new();
    let _ = buffer.read_line(&mut data);
    println!("read_buff got {}", data);
}
fn main() {
    read_buff(BufReader::new("Potato!".as_bytes()));
}

这打印read_buff got Potato!。对于这种情况,无需使用光标。

要使用BufWriter中内存中的String,您可以使用as_mut_vec方法。不幸的是,它是unsafe,我还没有找到任何其他方法。我不喜欢Cursor方法,因为它消耗了矢量,因此我还没有找到与BufWriter一起使用Cursor的方法。

use std::io::BufWriter;
use std::io::Write;
pub fn write_something<W: Write>(mut buf: BufWriter<W>) {
    buf.write("potato".as_bytes());
}
#[cfg(test)]
mod tests {
    use super::*;
    use std::io::{BufWriter};
    #[test]
    fn testing_bufwriter_and_string() {
        let mut s = String::new();
        write_something(unsafe { BufWriter::new(s.as_mut_vec()) });
        assert_eq!("potato", &s);
    }
}

最新更新