Rust Pattern - 读文件

简洁的写法

fn load_blacklist(filename: &str) -> Result<HashSet<String>> {
    File::open(Path::new(filename)).and_then(|mut f| {
        let mut buffer = String::new();
        f.read_to_string( &mut buffer ).and_then(|_| {
            Ok(buffer.as_str().lines().map(|s| s.trim().to_owned()).filter(|s| s.len() > 0).collect::<HashSet<_>>())
        })
    }).map_err(|e| e.into())
}

如果文件体积不大,可以用这种一步读取全文的方式进行处理。

另外,简洁的写法,会牺牲行数、时间等调试和统计数据的获取。

下面这种写法似乎更直观,更清晰;但是没有了.map, .and_then 之类方法的起承转合,似乎缺少了一些 Rust 的感觉。

fn load_category(filename: &str) -> Result<HashSet<String>> {
    let mut f = File::open(Path::new(filename))?;
    let mut buffer = String::new();
    f.read_to_string( &mut buffer )?;
    let cats : HashSet<_> = buffer.as_str().lines().map(|s| s.trim().to_owned()).filter(|s| s.len() > 0).collect();

    Ok(cats)
}

引入 BufReader,增加读缓冲

#[allow(dead_code)]
fn load_blacklist(filename: &str) -> Result<HashSet<String>> {
    let fp = File::open(Path::new(filename)).unwrap();
    let clock = Instant::now();
    let mut cats = HashSet::new();
    let mut n_in = 0;
    let mut n_bytes = 0;
    let reader = BufReader::with_capacity( 1024*1024*4, fp );
    for mut l in reader.lines().map(|r| r.unwrap()) {
        if !l.is_empty() && l.chars().rev().next().unwrap() == '\n' {
            l.pop();
        }
        let line = l.trim();
        if line.len() < 1 {
            continue;
        }
        n_in += 1;
        n_bytes += line.len();

        cats.insert( line.to_owned() );
    }

    let n_out = cats.len();
    let time_elapsed = clock.elapsed();
    let time_last = (time_elapsed.as_secs() as f64) + (time_elapsed.subsec_nanos() as f64 * 1e-9);
    let tps = if time_last > 0.0 { n_in as f64 / time_last as f64 } else { n_in as f64 };
    let bw  = (if time_last > 0.0 { n_bytes as f64 / time_last as f64 } else { n_bytes as f64 }) / 1048576_f64;
    info!("[STAT] parse {} last {:.2} seconds, in={} out={} tps={:.2} bw={:.2} MB/s\n", filename, time_last, n_in, n_out, tps, bw);

    Ok(cats)
}

使用 enumerate(),记录输入数据的行号

#[allow(dead_code)]
fn load_blacklist(filename: &str) -> Result<HashSet<String>> {
    let fp = File::open(Path::new(filename)).unwrap();
    let clock = Instant::now();
    let mut cats = HashSet::new();
    let mut n_in = 0;
    let mut n_bytes = 0;
    let reader = BufReader::with_capacity( 1024*1024*4, fp );
    for (ln, lo) in reader.lines().enumerate() {
        let mut l = match lo {
            Ok(s) => s,
            Err(e) => {
                stderr().write_all(format!("BAD LINE#{} error -- {:?}\n", ln, e).as_bytes()).unwrap();
                continue;
            },  
        };  
        if !l.is_empty() && l.chars().rev().next().unwrap() == '\n' {
            l.pop();
        }   
        let line = l.trim();
        if line.len() < 1 {
            continue;
        }
        n_in += 1;
        n_bytes += line.len();

        cats.insert( line.to_owned() );
    }

    let n_out = cats.len();
    let time_elapsed = clock.elapsed();
    let time_last = (time_elapsed.as_secs() as f64) + (time_elapsed.subsec_nanos() as f64 * 1e-9);
    let tps = if time_last > 0.0 { n_in as f64 / time_last as f64 } else { n_in as f64 };
    let bw  = (if time_last > 0.0 { n_bytes as f64 / time_last as f64 } else { n_bytes as f64 }) / 1048576_f64;
    info!("[STAT] parse {} last {:.2} seconds, in={} out={} tps={:.2} bw={:.2} MB/s\n", filename, time_last, n_in, n_out, tps, bw);

    Ok(cats)
}

当 filename == '-' 时,从标准输入(STDIN)读取

#[allow(dead_code)]
fn load_blacklist(filename: &str) -> Result<HashSet<String>> {
    let fp = match filename {
        "-" => Box::new(stdin()) as Box<Read>,
        filename => {
            let path = Path::new(filename);
            let fp = File::open(path).unwrap();
            Box::new(fp) as Box<Read>
        },
    };

    let clock = Instant::now();
    let mut cats = HashSet::new();
    let mut n_in = 0;
    let mut n_bytes = 0;
    let reader = BufReader::with_capacity( 1024*1024*4, fp );
    for mut l in reader.lines().map(|r| r.unwrap()) {
        if !l.is_empty() && l.chars().rev().next().unwrap() == '\n' {
            l.pop();
        }
        let line = l.trim();
        if line.len() < 1 {
            continue;
        }
        n_in += 1;
        n_bytes += line.len();

        cats.insert( line.to_owned() );
    }

    if filename != "-" {
        let n_out = cats.len();
        let time_elapsed = clock.elapsed();
        let time_last = (time_elapsed.as_secs() as f64) + (time_elapsed.subsec_nanos() as f64 * 1e-9);
        let tps = if time_last > 0.0 { n_in as f64 / time_last as f64 } else { n_in as f64 };
        let bw  = (if time_last > 0.0 { n_bytes as f64 / time_last as f64 } else { n_bytes as f64 }) / 1048576_f64;
        stderr().write_all(format!("[STAT] parse {} last {:.2} seconds, in={} out={} tps={:.2} bw={:.2} MB/s\n", filename, time_last, n_in, n_out, tps, bw).as_bytes()).unwrap();
    }

    Ok(cats)
}

转载于:https://my.oschina.net/kuerant/blog/1499366

Mac Rust io-uring是一种在Mac操作系统上使用Rust语言进行开发的io-uring库。 io-uring是Linux内核中的一个新特性,它为应用程序提供了一种高性能、高效率的异步I/O操作方式。它通过使用事件驱动和无锁技术,实现了在高并发环境下进行文件操作的优化。io-uring提供了更低的系统开销和更高的吞吐量,特别适用于需要大量I/O操作的应用程序。 虽然io-uring最初是为Linux内核设计的,但由于其高性能的特性,一些开发者试图将其移植到其他操作系统上。其中,Mac Rust io-uring就是一个在Mac操作系统上使用Rust语言实现io-uring的库。 使用Mac Rust io-uring,开发者可以在Mac环境下利用io-uring的特性来提高文件操作的性能。这对于需要进行大量I/O操作的应用程序来说,是一个很有价值的工具。例如,对于数据库、Web服务器或文件传输等应用,通过使用Mac Rust io-uring,可以显著提高其性能和吞吐量。 Mac Rust io-uring不仅提供了对io-uring的封装,还提供了一些更高级别的功能和接口,以方便开发者使用。开发者可以使用Mac Rust io-uring来实现一些高级的文件操作,例如批量取或写入文件,提高数据处理的效率。 总之,Mac Rust io-uring是一个在Mac操作系统上使用Rust语言开发的io-uring库,它能够为开发者提供高性能的异步I/O操作方式,从而提高应用程序的性能和吞吐量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值