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 算法
247,235 每月下载次数
在 225 个 crate 中使用 (15 个直接使用)
105KB
1.5K SLoC
buf_re(a)dux
替换 std::io
中的缓冲 I/O 类型。
这些替换保留了与stdlib对应的名称/签名和实现特质,使替换变得像交换类型导入一样简单。
更直接的控件
所有替换类型都提供方法
- 增加缓冲区的容量
- 获取可用字节数以及缓冲区的总容量
- 消耗包装器而不丢失数据
BufReader
提供方法
- 通过
&
引用访问缓冲区,而不执行 I/O - 无条件地将读取强制读入缓冲区
- 获取一个
Read
适配器,它清空缓冲区并直接从内部读取器读取 - 将字节向下移动到缓冲区的开始,为更多读取腾出空间
- 获取内部读取器和带有剩余数据的修剪后的缓冲区
BufWriter
和 LineWriter
提供方法
- 刷新缓冲区并无条件地展开内部写入器
更合理且可自定义的缓冲区行为
使用 policy
模块中的类型调整缓冲区行为以适应您的特定用例
-
通过实现
ReaderPolicy
特质来完善BufReader
的行为,或使用现有的实现,如MinBuffered
,以确保缓冲区始终包含一定数量的字节(直到底层读取器为空)。 -
通过实现
WriterPolicy
特质来完善BufWriter
的行为,或使用现有的实现,如FlushOn
,在缓冲区中出现特定字节时刷新(用于实现LineWriter
)。
使用方法
文档
Cargo.toml
:
[dependencies]
buf_redux = "0.2"
lib.rs
或 main.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 License,版本2.0(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可协议(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义的,任何有意提交给作品并由您提交的贡献,均应如上所述双重许可,不附加任何额外条款或条件。
依赖关系
~415–780KB
~11K SLoC