1 个不稳定版本
0.1.0 | 2019 年 12 月 22 日 |
---|
#1728 in 异步
16KB
240 行
async_buf_reader_utils
该 crate 的目的是为异步 BufReader 实现添加附加功能。
要将附加方法添加到异步 BufReader,只需将其添加到您的模块中
use async_buf_reader_utils::prelude::*;
方法
buf_reader.read_until_index_found(&mut predicate, &mut fillable).await
fn read_until_index_found<'a, F>(
&'a mut self,
predicate_found_index: &'a mut F,
buf: &'a mut Vec<u8>,
) -> ReadChunkUntilIndexFoundFuture<'a, Self, F>
示例
本示例的目标是加载一个文本文件,并异步地找到给定组中直到第 4 个逗号之前的一组字符。
如果输入文本文件是
1,50,0,3,17,1,212,3,1,3,4,3,1,5
我们希望能够返回
> 1,50,0,3,
> 17,1,212,3,
> 1,3,4,3,
> 1,5
以下是使用 async read_until_index_found 解决此问题的业务逻辑
fn main() {
let _result: Result<(), String> = async_std::task::block_on(async {
use async_buf_reader_utils::prelude::*;
use async_std::{fs::File, io::BufReader};
// Path to file you want to read asynchronously
let str_path = "./data/file.txt";
// Async load file (you can optionally use method with_capacity to limit how
// much async-std BufReader bytes are loaded while reading which is useful in memory sensative environments)
let mut buf = BufReader::with_capacity(12, File::open(&str_path).await.expect("should have opened file"));
let mut comma_count: usize = 0;
let mut last_comma_idx = None;
let mut fillable = vec![];
// Our predicate closure is our business logic,
// where we are trying to capture all characters up to
// the 4th comma, remembering that a regex won't be as useful here
// because our predicate will be called for every loaded chunk
// of data returned by our async BufReader, so a desired match
// might stretch across two different strings provided to the predicate.
// Once we've reached the 4th comma, return the index via Some(index) and reset
// our counters, otherwise return None to indicate we are still searching.
let mut predicate = |str_data: &str|->Option<usize>{
// println!("in predicate {:?}", str_data);
last_comma_idx = str_data.bytes().enumerate().find_map(|(i, x)| {
if x == b','{
comma_count += 1;
}
if comma_count == 4 {
Some(i)
}
else{
None
}
});
// println!("cur comma idx {:?}", last_comma_idx);
if let Some(idx) = last_comma_idx {
last_comma_idx = None;
comma_count = 0;
Some(idx)
}else{
None
}
};
// Start our async while loop passing our predicate and buffer to read_until_index_found,
// so our loop will continue returning the chunks of strings that are resulting
// from the returned indices in our predicate.
while let Ok(Some(_)) = buf.read_until_index_found(&mut predicate, &mut fillable).await {
println!("in while await loop {:?}", str::from_utf8(&fillable).unwrap());
fillable.clear();
}
Ok(())
});
}
依赖关系
~6–18MB
~208K SLoC