如何在 Rust 中解码和读取 zstd 文件?

问题描述 投票:0回答:1

我正在寻找一些关于如何解码和读取 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 之外还有其他推荐的软件包,请与我分享。我将不胜感激所有的帮助。

file rust io zstd
1个回答
0
投票

您正在以正确的方式进行操作,在

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())
}

再解释一下:

  • 因为
    File::open
    Decoder::new
    都会返回
    std::io::Error
    ,如果遇到问题,我们可以使用
    ?
    提前返回错误并避免嵌套
    if-let
  • Decoder::new
    接受阅读器类型并创建
    Decoder<'_, BufReader<_>>
    (即,它为
    BufReader
    本身创建
    File
    ),因此我们不必执行该部分。
  • 返回类型具有相互嵌套的所有层,但如果您愿意,可以在本例中将其替换为
    Result<Lines<impl BufRead>, IoError>
    以保持简洁。
© www.soinside.com 2019 - 2024. All rights reserved.