找不到字符串在文件中的位置,因为移动后会使用BufReader

时间:2018-07-09 15:38:00

标签: rust

我正在尝试创建一个返回文件中字符串位置的函数。这是我的代码:

use std::{
    fs::File,
    io::{BufRead, BufReader, Seek, SeekFrom},
};

fn find(log_file: &str, key: &str) -> Option<u64> {
    let log = File::open(log_file).unwrap();
    let mut reader = BufReader::new(log);
    for line in reader.lines() {
        let line = line.unwrap();
        if line.starts_with(&format!("{},", key)) {
            let bytes = line.as_bytes();
            let current_offset = reader.seek(SeekFrom::Current(0)).unwrap();
            return Some(current_offset - bytes.len() as u64);
        }
    }
    None
}

playground

当我尝试编译时,我得到:

error[E0382]: use of moved value: `reader`
  --> src/main.rs:13:34
   |
9  |     for line in reader.lines() {
   |                 ------ value moved here
...
13 |             let current_offset = reader.seek(SeekFrom::Current(0)).unwrap();
   |                                  ^^^^^^ value used here after move
   |
   = note: move occurs because `reader` has type `std::io::BufReader<std::fs::File>`, which does not implement the `Copy` trait

有什么办法可以使这项工作完成?

这个问题不是Cannot use moved BufReader after for loop with bufreader.lines()的重复,因为使用by_ref也不起作用,因为然后编译器告诉我读者是两次可变借用的。

1 个答案:

答案 0 :(得分:1)

我认为您应该在此处使用.read_line()。这比调用.lines()

更有效
use std::{
    fs::File,
    io::{BufRead, BufReader},
};

fn find(log_file: &str, key: &str) -> Option<u64> {
    let log = File::open(log_file).unwrap();
    let mut reader = BufReader::new(log);
    let mut line = String::new();
    let mut pos = 0;
    while let Ok(num) = reader.read_line(&mut line) {
        if num == 0 {
            break;
        }
        if line.starts_with(&format!("{},", key)) {
            return Some(pos);
        }
        pos += num as u64;
        line.clear();
    }
    None
}