2 个不稳定版本
使用旧的 Rust 2015
0.4.0 | 2019年9月13日 |
---|---|
0.3.0 | 2019年1月4日 |
#1209 在 解析器实现 中
30,307 每月下载量
在 15 个crate中使用了(8 个直接使用)
19KB
221 行
LineReader
概述
LineReader
是一个针对 Rust 的字节分隔缓冲读取器,旨在作为比 BufRead::read_until
更快、更不易出错的选择。
它提供了三个主要功能
next_line() -> Option<io::Result<&[u8]>>
在文件末尾返回 None
,或返回从读取器读取的下一行字节切片的 io::Result
包装。
行长度限制为内部缓冲区的大小 - 较长的行将在多个读取中分散。
与 read_until
相比,使用 Option
检测文件末尾更为自然;行长度自然限制在某个合理的值,而无需使用 by_ref().take(limit)
;通过返回借用切片来最小化复制;您永远不会忘记调用 buf.clear()
。
next_batch() -> Option<io::Result<&[u8]>>
行为与 next_line()
相同,但它返回缓冲区中所有完整行的切片。
for_each() -> io::Result<()>
在输入的每一行上调用闭包,当闭包返回 Ok(true)
且没有检测到 IO 错误时。此类错误将终止迭代并从函数返回。
示例
extern crate linereader;
use linereader::LineReader;
let mut file = File::open(myfile).expect("open");
// Defaults to a 64 KiB buffer and b'\n' delimiter; change with one of:
// * LineReader::with_capacity(usize);
// * LineReader::with_delimiter(u8);
// * LineReader::with_delimiter_and_capacity(u8, usize)
let mut reader = LineReader::new(file);
while let Some(line) = reader.next_line() {
let line = line.expect("read error");
// line is a &[u8] owned by reader.
}
安全性
LineReader
不包含 unsafe
代码,但它确实会手动分发来自内部缓冲区的手动计算的切片位置,而 Rust 执行的唯一强制措施是确保它们保持在缓冲区内部。
没有不完整的行检测,根据文档,超出配置缓冲区的行可以分布在多个“行”中,只有缺少终止符作为提示。应该注意,这不会导致使用库的代码中出现不期望的行为。
如get_mut()
等方法提供了对封装的读取器的直接访问,如果没有同时调用reset()
,如果读取器的状态发生改变,可能会出现不期望的行为。
替代方案
bstr:从0.2.8版本开始,for_byte_line
和for_byte_line_with_terminator
BufRead
扩展特质函数应该具有类似的功能,没有LineReader
的行长度限制。
性能
使用'Dickens_Charles_Pickwick_Papers.xml'进行的测试,将其自身连接480次。生成的文件大小为976 MB,有1030万行。
Westmere Xeon 2.1GHz,FreeBSD/ZFS。
方法 | 时间 | 行/秒 | 带宽 |
---|---|---|---|
read() | 0.25s | 41429738/s | 3907.62 MB/s |
LR::next_batch() | 0.27s | 38258946/s | 3608.55 MB/s |
LR::next_line() | 1.51s | 6874006/s | 648.35 MB/s |
read_until() | 1.94s | 5327387/s | 502.47 MB/s |
read_line() | 2.54s | 4081562/s | 384.97 MB/s |
lines() | 3.23s | 3199491/s | 301.77 MB/s |
依赖关系
~170–310KB