3 个稳定版本
新 1.0.2 | 2024 年 8 月 5 日 |
---|---|
1.0.1 | 2024 年 3 月 4 日 |
1.0.0 | 2023 年 3 月 18 日 |
#46 在 算法
72,756 每月下载量
在 109 个crate中(5 直接)使用
100KB
1.5K SLoC
buffer-re(a)dux
未维护的
buf_redux
的分支。
在 std::io
中替换缓冲 I/O 类型。
这些替换保留了其stdlib对应者的方法名称/签名和实现的特质,使得替换就像交换类型的导入一样简单。
更多直接控制
所有替换类型都提供方法来
- 增加缓冲区的容量
- 获取可用字节数以及缓冲区的总容量
- 消费包装器而不会丢失数据
BufReader
提供方法来
- 通过
&
-引用访问缓冲区而不执行 I/O - 强制无条件读取到缓冲区
- 获取一个
Read
适配器,该适配器清空缓冲区然后直接从内部读取器中拉取 - 将字节向下移动到缓冲区的开始,为更多读取腾出空间
- 获取内部读取器和带有剩余数据的修剪缓冲区
BufWriter
和 LineWriter
提供方法来
- 刷新缓冲区并无条件地展开内部写入器。
更合理且可自定义的缓冲区行为
使用 policy
模块中的类型调整缓冲区的行为以适应您的特定用例
-
通过实现
ReaderPolicy
特质或使用现有的实现(如MinBuffered
)来细化BufReader
的行为,以确保缓冲区始终包含一定数量的字节(直到底层读取器为空)。 -
通过实现
WriterPolicy
特质或使用现有的实现(如FlushOn
)来细化BufWriter
的行为,当缓冲区中出现特定的字节时刷新(用于实现LineWriter
)。
使用方法
文档
Cargo.toml
:
[dependencies]
buffer-redux = "0.2"
然后简单地交换要替换的类型导入
BufReader
:
- use std::io::BufReader;
+ use buffer_redux::BufReader;
BufWriter
:
- use std::io::BufWriter;
+ use buffer_redux::BufWriter;
LineWriter
:
- use std::io::LineWriter;
+ use buffer_redux::LineWriter;
使用 MinBuffered
新的 policy::MinBuffered
读取策略可以确保 BufReader
的缓冲区中始终至少有特定数量的字节。这对于需要一定前瞻能力的解析应用非常有用。
use buffer_redux::BufReader;
use buffer_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 版(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则任何有意提交以包含在您的工作中的贡献,根据 Apache-2.0 许可证定义,应按上述方式双许可,而无需任何额外条款或条件。
依赖关系
~110–495KB