rust - 如何从文件向量创建单个流?
问题描述
我正在尝试读取多个文件,我想从文件路径向量创建一个流。我一直在与编译器斗争一段时间,但我不确定如何使这项工作:
fn formatted_tags_stream(
args: &[&str],
files: &Vec<PathBuf>,
) -> Result<impl Iterator<Item = String>> {
// Transform list of paths into a list of files
let files: Vec<File> = files.into_iter().map(|f| File::open(f)).flatten().collect();
// Here is where I'm stuck :/
let stream =
files
.into_iter()
.skip(1)
.fold(BufReader::new(files[0]), |acc, mut f| acc.chain(f));
Ok(BufReader::new(stream).lines().filter_map(|line| {
line.ok().and_then(|tag| {
if let Ok(tag) = serde_json::from_str::<TagInfo>(&tag) {
Some(tag.format())
} else {
None
}
})
}))
}
解决方案
如果使用fold
,则函数必须始终返回相同的类型。但是,如果您在编写时使用它,该函数将采用一个类型并在第一遍中F
返回 a 。Chain<F, ...>
下一次传递需要采用 aChain<F, ...>
并返回 a Chain<Chain<F, ...>, ...>
- 导致“每次迭代不同类型”。这是行不通的,因为 Rust 想知道确切的类型,并且类型必须保持不变。
但是,您可以对事物进行类型擦除并将其隐藏在指针后面(即Box
,点“特征对象”)。见这里(我做了一些小的调整以使其编译):
use std::path::PathBuf;
use std::fs::File;
use std::io::BufReader;
use std::io::Read;
use std::io::BufRead;
fn formatted_tags_stream(
args: &[&str],
files: &Vec<PathBuf>,
) -> Result<impl Iterator<Item = String>, ()> {
// Transform list of paths into a list of files
let files: Vec<File> = files.into_iter().map(|f| File::open(f)).flatten().collect();
// Here is where I'm stuck :/
let bufreader = Box::new(std::io::empty()) as Box<dyn Read>;
let stream =
files
.into_iter()
.fold(bufreader, |acc, f| Box::new(acc.chain(f)) as Box<dyn Read>);
Ok(BufReader::new(stream).lines().filter_map(|line| {
line.ok().and_then(|tag| {
if let Ok(_tag) = tag.parse::<usize>() {
Some(tag)
} else {
None
}
})
}))
}
请注意,使用 aBox<dyn Read>
会产生一些运行时开销,因为它会导致动态调度。
推荐阅读
- camel-rest - apache camel REST 失败并出现 [Error Creating bean with name 'rest-configuration']
- typescript - 如何在我的节点项目中离线运行无服务器?
- java - 如何防止 Spring Boot AOP 删除类型注释?
- c# - 如何将方法委托绑定为组合框的值
- javascript - 在用javascript上传到服务器之前,将文件读取为字节并进行base64编码
- c# - 创建视图和表之间的关系
- vagrant - Vagrant shell provisioner 重复五次
- coldfusion - CFLDAP 名称属性...不能使用结构?
- android - Google 控制台 APK 上传 - 新应用程序失败
- jquery - 如何为数组中的元素获取与这些输入标签关联的文本