正式开始
本节需要做一个类似grep的工具 rgrep
- grep 命令用于查找文件里符合条件的字符串。如果发现某个文件的内容符合所指定的字符串,grep 命令会把含有字符串的那一行显示出;
- 若不指定任何文件名称,或是所给予的文件名为 -,grep 命令会从标准输入设备读取数据
rgrep简单场景
- 给定一个字符串以及一个文件,打印出文件中所有包含该字符串的行
- 放宽限制,允许用户提供一个正则表达式,来查找文件中所有包含该字符串的行
- 进一步放宽限制,允许用户提供一个正则表达式,来查找满足文件通配符的所有文件
操作提示
- 对于命令行的部分,你可以使用 命令行解析库 clap 或者 命令行解析库 structopt,也可以就用 env.args()。
- 对于正则表达式的支持,可以使用 regex。
- 至于文件的读取,可以使用 std::fs 或者 tokio::fs。你可以顺序对所有满足通配符的文件进行处理,也可以用 rayon 或者 tokio 来并行处理
- 对于输出的结果,最好能把匹配的文字用不同颜色展示
好用链接
处理通配符 globset 处理通配符 glob 命令行解析库 clap 命令行解析库 structopt 正则表达式处理库 标准库文件处理 tokio 异步文件处理 文件并发处理 tokio异步处理库 error.rs
如何写出好实现
剥离主要逻辑
- 是对于单个文件的 grep,也就是代码中标记的部分,将它抽离成一个函数、
fn process<R: Read>(reader: BufReader<R>)
- 为了可测试,需要 把输出的对象从 Stdout 抽象成 Write
fn process<R: Read, W: Write>(reader: BufReader<R>, writer: &mut Writer)
a. 这样,我们就可以使用实现了 Read trait 的 &[u8] 作为输入,以及使用实现了 Write trait 的 Vec 作为输出,进行测试了。
b. 而在 rgrep 的实现时,我们用 File 作为输入,Stdout 作为输出
精选问答
-
use std::io::self self在这里指的是什么啊
a. 就是 std::io
b. 一般 use std::io 就可以了,但如果想同时引入自己以及自己底下的结构,可以用 self,比如: use std::io::{self, Read};