提问人:TrkDgnr 提问时间:10/17/2023 更新时间:10/17/2023 访问量:117
如何在 Rust 中解码和读取 zstd 文件?
How to decode and read a zstd file in Rust?
问:
我正在寻找一些关于如何解码和读取 zstd 文件的建议,我感到有点迷茫,因为这是我开始学习 Rust 以来的第一个大项目。
我在这个项目中使用 Rust,因为它是为了实习,而且数据导出/压缩工具很久以前就用 Rust 编写了,所以我想我可以从中获得一些灵感。我正在从头开始学习 Rust,所以我对文件 I/O 进程的结构和功能不是很熟悉。我有一个代码片段目前不起作用,所以我有一些问题:
use std::fs::File;
use std::io::{self, BufReader};
use zstd::stream::read::Decoder;
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where P: AsRef<Path>, {
if let Ok(file) = File::open(filename) {
if let Ok(buf_reader) = BufReader::new(file) {
if let Ok(decoder) = Decoder::new(buf_reader) {
return Ok(io::BufReader::new(decoder).lines()); } } } }
if let Ok(lines) = read_lines(filename) {
for line in lines {
if let Ok(ip) = line {
println!("{}", ip)
}
}
}
既然是压缩文件,我是否应该先将其整体解码,然后开始逐行读取?我知道解压缩的文件是jsonl格式,所以每一行都是一个单独的json文件。如果文件大小太大而无法一口气读完,我该怎么办?
另外,如果您有您正在使用的 zstd 以外的其他软件包,请与我分享。我将不胜感激所有的帮助。
答:
2赞
kmdreko
10/17/2023
#1
你以正确的方式去做,使用 in a 将允许您从压缩文件中读取行,而无需预先加载整个文件。用于读取行的外部将从解码器读取块,直到到达换行符,从解码器读取将从文件中解码块。Decoder
BufReader
BufReader
您只是没有正确的结构和返回类型。这是我会做的:
use std::fs::File;
use std::io::{BufRead, BufReader, Error as IoError, Lines};
use std::path::Path;
use zstd::stream::read::Decoder;
fn read_lines<P>(filename: P) -> Result<Lines<BufReader<Decoder<'static, BufReader<File>>>>, IoError>
where
P: AsRef<Path>,
{
let file = File::open(filename)?;
let decoder = Decoder::new(file)?;
Ok(BufReader::new(decoder).lines())
}
再解释一下:
- 由于如果遇到问题,两者都会返回,因此我们可以使用它来尽早返回错误并避免嵌套 S。
File::open
Decoder::new
std::io::Error
?
if-let
Decoder::new
接受一个读取器类型并创建一个(即它为它本身创建一个),所以我们不必做那部分。Decoder<'_, BufReader<_>>
BufReader
File
- 返回类型将所有图层嵌套在一起,但如果您愿意,可以将其替换为本实例以保持简洁。
Result<Lines<impl BufRead>, IoError>
评论
BufReader