#buffer #io #buffered

停止维护 buf_redux

std::io 中替换缓冲 I/O 的模块,具有额外功能

20 个版本

使用旧 Rust 2015

0.8.4 2019 年 7 月 31 日
0.8.1 2018 年 11 月 22 日
0.7.1 2018 年 6 月 15 日
0.6.3 2018 年 2 月 9 日
0.2.0 2016 年 2 月 27 日

#2383 in 算法

Download history 64688/week @ 2024-03-14 63449/week @ 2024-03-21 56140/week @ 2024-03-28 55640/week @ 2024-04-04 54647/week @ 2024-04-11 59026/week @ 2024-04-18 54960/week @ 2024-04-25 53650/week @ 2024-05-02 53439/week @ 2024-05-09 50511/week @ 2024-05-16 49167/week @ 2024-05-23 55717/week @ 2024-05-30 56900/week @ 2024-06-06 56758/week @ 2024-06-13 66848/week @ 2024-06-20 56290/week @ 2024-06-27

247,235 每月下载次数
225 crate 中使用 (15 个直接使用)

MIT/Apache

105KB
1.5K SLoC

buf_re(a)dux

Travis Crates.io Crates.io Crates.io

替换 std::io 中的缓冲 I/O 类型。

这些替换保留了与stdlib对应的名称/签名和实现特质,使替换变得像交换类型导入一样简单。

更直接的控件

所有替换类型都提供方法

  • 增加缓冲区的容量
  • 获取可用字节数以及缓冲区的总容量
  • 消耗包装器而不丢失数据

BufReader 提供方法

  • 通过 & 引用访问缓冲区,而不执行 I/O
  • 无条件地将读取强制读入缓冲区
  • 获取一个 Read 适配器,它清空缓冲区并直接从内部读取器读取
  • 将字节向下移动到缓冲区的开始,为更多读取腾出空间
  • 获取内部读取器和带有剩余数据的修剪后的缓冲区

BufWriterLineWriter 提供方法

  • 刷新缓冲区并无条件地展开内部写入器

更合理且可自定义的缓冲区行为

使用 policy 模块中的类型调整缓冲区行为以适应您的特定用例

  • 通过实现 ReaderPolicy 特质来完善 BufReader 的行为,或使用现有的实现,如 MinBuffered,以确保缓冲区始终包含一定数量的字节(直到底层读取器为空)。

  • 通过实现 WriterPolicy 特质来完善 BufWriter 的行为,或使用现有的实现,如 FlushOn,在缓冲区中出现特定字节时刷新(用于实现 LineWriter)。

使用方法

文档

Cargo.toml:

[dependencies]
buf_redux = "0.2"

lib.rsmain.rs

extern crate buf_redux;

然后只需简单地交换您想要替换的类型导入即可

BufReader:

- use std::io::BufReader;
+ use buf_redux::BufReader;

BufWriter:

- use std::io::BufWriter;
+ use buf_redux::BufWriter;

LineWriter:

- use std::io::LineWriter;
+ use buf_redux::LineWriter;

使用 MinBuffered

新的policy::MinBuffered读取策略可以确保BufReader的缓冲区至少包含一定数量的字节。这对于需要一定预读量的解析应用非常有用。

use buf_redux::BufReader;
use buf_redux::policy::MinBuffered;
use std::io::{BufRead, Cursor};

let data = (1 .. 16).collect::<Vec<u8>>();

// normally you should use `BufReader::new()` or give a capacity of several KiB or more
let mut reader = BufReader::with_capacity(8, Cursor::new(data))
    // always at least 4 bytes in the buffer (or until the source is empty)
    .set_policy(MinBuffered(4)); // always at least 4 bytes in the buffer

// first buffer fill, same as `std::io::BufReader`
assert_eq!(reader.fill_buf().unwrap(), &[1, 2, 3, 4, 5, 6, 7, 8]);
reader.consume(3);

// enough data in the buffer, another read isn't done yet
assert_eq!(reader.fill_buf().unwrap(), &[4, 5, 6, 7, 8]);
reader.consume(4);

// `std::io::BufReader` would return `&[8]`
assert_eq!(reader.fill_buf().unwrap(), &[8, 9, 10, 11, 12, 13, 14, 15]);
reader.consume(5);

// no data left in the reader
assert_eq!(reader.fill_buf().unwrap(), &[13, 14, 15]);

注意:留出空间/环形缓冲区/slice-deque特性

使用如MinBuffered这样的策略,它会将数据读入缓冲区并消耗字节,而不会将其完全清空。在这种情况下,正常缓冲区的处理可能会耗尽读取/写入的空间,因为所有空闲空间都在缓冲区的头部。如果缓冲区中的数据量很小,您可以在缓冲类型上调用.make_room()来为读取腾出更多空间。MinBuffered会自动执行此操作。

与此不同,通过slice-deque特性,您可以使用::new_ringbuf()::with_capacity_ringbuf()构造函数来代替::new()with_capacity(),分别。有了环形缓冲区,从缓冲区中消耗/刷新字节会立即在末尾腾出更多空间用于读取/写入。然而,这也存在一些注意事项

  • 此特性仅适用于具有虚拟内存支持的目标平台,即像Windows这样的完整操作系统以及像Linux、OS X、BSD变体等Unix派生平台。

  • 默认容量根据平台而异,自定义容量会被四舍五入到其最小尺寸的倍数,通常是平台的页面大小。由于一些历史原因,Windows的最小尺寸相当大(64 KiB),因此在某些情况下,这可能不如默认缓冲区容量(8 KiB)优化。

  • 由于虚拟内存技巧的性质,缓冲区分配的虚拟地址空间将是其实际容量的两倍。这意味着如果使用相同容量的普通缓冲区,您的程序将看起来使用了更多的内存。在两种情况下,物理内存使用量将相同,但如果地址空间在您的应用中(32位目标)非常宝贵,那么这可能会成为一个问题。

是否值得权衡利弊取决于您。使用如MinBuffered这样的策略可能会显著提高性能。

许可协议

根据您的要求,许可协议为以下之一:

任选其一。

贡献

除非您明确声明,否则根据Apache-2.0许可证定义的,任何有意提交给作品并由您提交的贡献,均应如上所述双重许可,不附加任何额外条款或条件。

依赖关系

~415–780KB
~11K SLoC