#io #buffered #no-alloc #read-file

nightly no-std buffed

解析缓冲 IO 的特质和实现

1 个不稳定版本

0.1.0 2023年2月20日

#2013解析器实现

MIT/Apache

270KB
670

pipeline coverage lib.rs docs.rs chat

buffed,一个用于 Rust 的增强缓冲读取器。

buffed 提供类似于 std::io::BufRead 的特性和实现。 buffed 的特性和结构允许直接从字节流中读取序列化数据。它不需要输入中的任何结构,同时利用缓冲机制。它还使得避免复制和分配变得容易。

注意:这个包主要是作为一个个人挑战制作的。它尚未经过适当的测试或审计,你不应该用它做任何事情比爱好更严肃的事情。考虑使用 sequoia-pgpbuffered-reader。我们仍然乐意接受问题和合并拉取请求!我们仍然希望这个包成为一个很好的抽象。

问题的根本

这个包最初是为了解决以下问题而设计的:读取一个用户提供的,UTF8 编码的文本文件,并通过它读取一些数据。以 闪电般快速tm 的速度执行,永远不占用内存,同时还能对恶意输入具有鲁棒性。

对速度的要求意味着要使用缓冲,这已经限制了我们可以使用的标准库中的内容

标准库也不允许使用合理的高级API来控制分配(我们也不期望它这样做),这可能会使事物更快。

buffed的API

buffed提供了一些特性

  • BuffedRead,类似于 std::io::BufRead,但在缓冲和允许读取实现 FromBytes 的类型方面提供了更多控制,无需复制。
  • FromBytes(以及相关的 FromBytesError),封装了读取数据的解析(和错误报告)逻辑。计划是为此特性实现大多数你可能需要的类型,如 nom 的解析器输出、serde 可序列化类型等。如果你希望为某些内容实现它,请提交问题/PR!只要它是在非默认的可选功能之后,合并它应该很容易。
  • Buffer,是 BuffedReader 缓冲区的特性。它可以被其他 BuffedRead 实现使用,以利用比 BuffedReader 使用的技术更先进的缓冲技术。

还有一些类型

  • BuffedReader,对于 BuffedRead,就像 BufReader 对于 BufRead。这是一个默认实现,包装了另一个实现 std::io::Read 的类型。值得注意的是,它使用了一个 BoxBuffer,可以根据需要替换为另一个 Buffer 的实现。
  • BoxBuffer,基于简单的 Box 字节切片的“默认”实现(Box<[u8]>)。
  • Error,是 BuffedRead 使用的通用错误类型。

示例

使用 Buffedread API 读取文件的全部内容可能如下所示

use std::fs::File;

use buffed::{BuffedRead, BuffedReader, FromBytes};

fn main() {
    let file = File::open("tests/assets/capital-ru.txt").unwrap();
    let mut r = BuffedReader::new(file);
    loop {
        match r.fill_buf() {
          // EOF
          Ok("") => { return; }
          Ok(data) => {
            let size = data.size();
            // Do something with data
            // ...
            r.consume(size).unwrap();
          },
          // Oopsies
          Err(err) => panic!("{err}"),
        }
    }
}

或者,BuffedReadrequire_fill_buf(amount: usize) 方法接受一个最小数据量,当达到(除非 EOF)时返回,而 require_fill_buf_no_alloc(amount: usize) 做同样的操作,但如果缓冲区需要重新分配以容纳数据量,则出错。

替代方案

如果你在寻找类似 buffed 的东西,你可能对以下内容感兴趣

  • buffered-reader:为 sequoia-pgp 项目提供的缓冲读取器实现。它完成了我们想要的所有事情,包括使用其堆叠读取器的概念解析对象的方式。它也是一个经过更多实战测试和更健壮的实现!如果你打算将 buffed 用于比业余爱好更严肃的事情,你应该考虑使用这个替代方案。
  • 使用类似 serdenom 的crate使用 std::io 类型实现定制的解决方案。这并不是最容易的道路,但如果其他方法不适合你的情况,这可能是最好的选择。

以下内容也可能有价值,尽管我们不会考虑使用它们,原因如下:

  • io-enum:与buffed实现相同,但不需要扩展std的特质,仅适用于枚举。
  • buf_redux:替代了std::io的缓冲类型,但仍仅读取字节,这使得在不复制的情况下处理UTF8变得困难且笨拙。自2019年8月以来没有发布新版本。
  • text_io:基于宏的无缓冲方法。我们发现它过于脆弱,并且一年内没有多少活动。
  • ciborium-io:为#![no_std]提供了简单的ReadWrite特质。大部分功能不完整,自2021年12月以来没有活动。
  • layered-io:在类似buffed的思想下扩展了stdReadWrite特质,但没有增加太多。

无运行时依赖

功能