rust - 如何将多个字节“读取”到“Vec”中?
问题描述
我有一种情况,我有一个目的地Vec
,我想准确地将n
我从Read
对象中读取的字节推送到该目的地。
Read
但是,通常处理切片。唯一使用的方法Vec
是read_to_end
,但我需要将读数“绑定”到仅n
字节。
到目前为止,我可以看到 3 种方法来实现这一点,但我不确定我是否遗漏了什么,或者哪一个是最好的(或至少是最不坏的):操场
read_to_end
无论如何使用
这是迄今为止最短的,但它也涉及最多的 stdlib 理解,我不确定我是否完全/正确地掌握了语义:
fn read1<T: Read>(mut reader: T, n: usize, sink: &mut Vec<u8>) -> Result<()> {
reader.take(n as u64).read_to_end(sink)?;
Ok(())
}
如果这不是一个实用功能,我认为by_ref
为了不消耗源阅读器也很有用?
扩展Vec
并读入该缓冲区
这涉及更多,并且存在我们向其中添加完全无效数据Vec
以便有适当的“切片”读取的问题:
fn read2<T: Read>(mut reader: T, n: usize, sink: &mut Vec<u8>) -> Result<()> {
let before = sink.len();
let after = sink.len() + n;
sink.resize(after, 0);
if let Err(e) = reader.read_exact(&mut sink[before..after]) {
sink.resize(before, 0);
return Err(e.into());
}
Ok(())
}
这假设read_exact
并且resize
(向下)不要惊慌。
使用本地缓冲区
这是最简单和最复杂的:重复读取数据到本地缓冲区,然后从本地缓冲区复制到输出 vec。
fn read3<T: Read>(mut reader: T, mut n: usize, sink: &mut Vec<u8>) -> Result<()> {
let before = sink.len();
let mut buf = [0;64];
while n > 0 {
let b = &mut buf[0..min(64, n)];
if let Err(e) = reader.read_exact(b) {
sink.resize(before, 0);
return Err(e.into());
}
sink.extend(&*b);
n -= b.len();
}
Ok(())
}
这是我会用较低级别的语言做的,但它会让人恶心。与版本 2 相比,它确实向输出 vec 添加了我们可能需要删除的数据(我在这里选择这样做,但可能存在不必要的情况),但与解决方案 2 不同的是,它向 vec 添加了部分数据,它是有效的数据。
解决方案
推荐阅读
- python - 如何填补时间序列数据中缺失的观测值
- java - 如何在不使用 mockito 执行代码的情况下从方法返回值
- javascript - 在同一选项卡中打开的其他网站可访问的全局变量
- jquery - 如何从 Jquery Ajax 成功数据中更新选择选项
- java - 如何在 Android Studio 中除 MainActivity 之外的其他类中调试?
- reactjs - 状态存在但未发生函数错误。this.setState 不是函数
- java - 在黄瓜特征文件中并行运行场景,一次一个特征文件
- actions-on-google - 不能在不是使用自定义类别创建的项目中指定自定义操作
- android - 批准 Android 上的后台定位?
- pyspark - 如何遍历代码存储库中的 json 文件并增量附加到数据集