从实现Read的类型中读取任意数量的字节 [英] Read an arbitrary number of bytes from type implementing Read

查看:141
本文介绍了从实现Read的类型中读取任意数量的字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的东西是;目前它是一个文件。我想从中读取一些仅在运行时已知的字节(二进制数据结构中的长度前缀)。

I have something that is Read; currently it's a File. I want to read a number of bytes from it that is only known at runtime (length prefix in a binary data structure).

所以我试过这个:

let mut vec = Vec::with_capacity(length);
let count = file.read(vec.as_mut_slice()).unwrap();

count 为零,因为 vec.as_mut_slice()。len()也为零。

[0u8; length] 当然不起作用,因为在编译时必须知道大小。

[0u8;length] of course doesn't work because the size must be known at compile time.

我想做

let mut vec = Vec::with_capacity(length);
let count = file.take(length).read_to_end(vec).unwrap();

但是的接收器参数是 T 我只有& mut T (我不确定为什么还需要它。)

but take's receiver parameter is a T and I only have &mut T (and I'm not really sure why it's needed anyway).

我想我可以用 BufReader 替换文件并跳舞周围有 fill_buf 消耗这听起来很复杂但我仍然想知道:我忽略了什么吗?

I guess I can replace File with BufReader and dance around with fill_buf and consume which sounds complicated enough but I still wonder: Have I overlooked something?

推荐答案

1。填充此向量版本



您的第一个解决方案即将开始工作。您发现了问题,但没有尝试解决它!问题是无论向量的容量如何,它仍然是空的( vec.len()== 0 )。相反,你实际上可以用空元素填充它,例如:

1. Fill-this-vector version

Your first solution is close to work. You identified the problem but did not try to solve it! The problem is that whatever the capacity of the vector, it is still empty (vec.len() == 0). Instead, you could actually fill it with empty elements, such as:

let mut vec = vec![0u8; length];

以下完整代码有效:

#![feature(convert)] // needed for `as_mut_slice()` as of 2015-07-19

use std::fs::File;
use std::io::Read;

fn main() {
    let mut file = File::open("/usr/share/dict/words").unwrap();
    let length: usize = 100;
    let mut vec = vec![0u8; length];
    let count = file.read(vec.as_mut_slice()).unwrap();
    println!("read {} bytes.", count);
    println!("vec = {:?}", vec);
}

当然,您还需要检查是否计数== length ,如果不是这样,请将更多数据读入缓冲区。

Of course, you still have to check whether count == length, and read more data into the buffer if that's not the case.

您的第二个解决方案更好,因为您不必检查已读取的字节数,并且您不必重新读取以防 count!= length 。您需要在读取特征上使用 bytes()函数(由 File <实现/ code>)。这将文件转换为流(即迭代器)。因为错误仍然可能发生,你不会得到 Iterator< Item = u8> 但是 Iterator< Item = Result< u8,R ::错误>> 。因此,您需要在迭代器中明确地处理失败。为简单起见,我们将在这里使用 unwrap()

Your second solution is better because you won't have to check how many bytes have been read, and you won't have to re-read in case count != length. You need to use the bytes() function on the Read trait (implemented by File). This transform the file into a stream (i.e an iterator). Because errors can still happen, you don't get an Iterator<Item=u8> but an Iterator<Item=Result<u8, R::Err>>. Hence you need to deal with failures explicitly within the iterator. We're going to use unwrap() here for simplicity:

use std::fs::File;
use std::io::Read;

fn main() {
    let file = File::open("/usr/share/dict/words").unwrap();
    let length: usize = 100;
    let vec: Vec<u8> = file
        .bytes()
        .take(length)
        .map(|r: Result<u8, _>| r.unwrap()) // or deal explicitly with failure!
        .collect();
    println!("vec = {:?}", vec);
}

这篇关于从实现Read的类型中读取任意数量的字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆