如何从 Vec 或 Slice 读取 (std::io::Read)?

2024-04-15

Vec支持std::io::Write,因此可以编写需要File or Vec, 例如。从 API 参考来看,两者都不是Vec也不支持切片std::io::Read.

有没有方便的方法来实现这一目标?是否需要编写包装结构?

这是一个工作代码的示例,它读取和写入一个文件,其中注释了一行应该读取向量。

use ::std::io;

// Generic IO
fn write_4_bytes<W>(mut file: W) -> Result<usize, io::Error>
    where W: io::Write,
{
    let len = file.write(b"1234")?;
    Ok(len)
}

fn read_4_bytes<R>(mut file: R) -> Result<[u8; 4], io::Error>
    where R: io::Read,
{
    let mut buf: [u8; 4] = [0; 4];
    file.read(&mut buf)?;
    Ok(buf)
}

// Type specific

fn write_read_vec() {
    let mut vec_as_file: Vec<u8> = Vec::new();

    {   // Write
        println!("Writing Vec... {}", write_4_bytes(&mut vec_as_file).unwrap());
    }

    {   // Read
//      println!("Reading File... {:?}", read_4_bytes(&vec_as_file).unwrap());
        //                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        //                               Comment this line above to avoid an error!
    }
}

fn write_read_file() {
    let filepath = "temp.txt";
    {   // Write
        let mut file_as_file = ::std::fs::File::create(filepath).expect("open failed");
        println!("Writing File... {}", write_4_bytes(&mut file_as_file).unwrap());
    }

    {   // Read
        let mut file_as_file = ::std::fs::File::open(filepath).expect("open failed");
        println!("Reading File... {:?}", read_4_bytes(&mut file_as_file).unwrap());
    }
}

fn main() {
    write_read_vec();
    write_read_file();
}

此操作失败并出现以下错误:

error[E0277]: the trait bound `std::vec::Vec<u8>: std::io::Read` is not satisfied
  --> src/main.rs:29:42
   |
29 |         println!("Reading File... {:?}", read_4_bytes(&vec_as_file).unwrap());
   |                                          ^^^^^^^^^^^^ the trait `std::io::Read` is not implemented for `std::vec::Vec<u8>`
   |
   = note: required by `read_4_bytes`

我想为文件格式编码器/解码器编写测试,而不必写入文件系统。


虽然向量不支持std::io::Read,切片即可。

由于 Rust 能够强制执行,因此造成了一些混乱Vec在某些情况下会分成一片,但在其他情况下则不会。

在这种情况下,需要对切片进行显式强制转换,因为在应用强制转换的阶段,编译器不知道Vec<u8> doesn't实施Read.


当使用以下方法之一将向量强制转换为切片时,问题中的代码将起作用:

  • read_4_bytes(&*vec_as_file)
  • read_4_bytes(&vec_as_file[..])
  • read_4_bytes(vec_as_file.as_slice()).

Note:

  • 最初提出问题时,我正在考虑&Read代替Read。这使得传递对切片的引用失败,除非我传入了&&*vec_as_file我不想这么做。
  • 您也可以使用最新版本的 Rustas_slice()将 Vec 转换为切片。
  • 感谢@arete#rust为了找到解决方案!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 Vec 或 Slice 读取 (std::io::Read)? 的相关文章

随机推荐