首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试在rust中迭代2个文件

尝试在rust中迭代2个文件
EN

Stack Overflow用户
提问于 2021-04-19 09:14:09
回答 2查看 70关注 0票数 0

我正在尝试读取2个文件,并比较每个文件中的每个项目,看看它们是否相等。

代码语言:javascript
复制
use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    let filename1 = "file1.txt";
    let filename2 = "file2.txt";

    // Open the file in read-only mode (ignoring errors).
    let file = File::open(filename1).unwrap();
    let reader = BufReader::new(file);

    let file2 = File::open(filename2).unwrap();
    let mut reader2 = BufReader::new(file2);

    // Read the file line by line using the lines() iterator from std::io::BufRead.
    for line1 in reader.lines() {

        let line = line.unwrap(); // Ignore errors.

        for line2 in reader2.lines() {
            let line2 = line2.unwrap(); // Ignore errors.
            
            if line2 == line1 {
                println!("{}",line2)
            }

        }
    }
}

然而,这不起作用。如何在带有缓冲区的循环上应用循环?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-19 20:45:01

您的第一个问题是this question的重复。如果你想在调用reader2lines方法后能够重用它,你需要调用by_ref。在下一次循环迭代中)。

这样,您的代码将被编译,但不会工作,因为一旦您处理完第一个文件的第一行,您就在第二个文件的末尾,所以在处理后续行时,第二个文件将显示为空。你可以通过倒带每一行的第二个文件来解决这个问题。使您的代码正常工作的最小更改集是:

代码语言:javascript
复制
use std::io::Read;
use std::io::Seek;
use std::io::SeekFrom;
use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    let filename1 = "file1.txt";
    let filename2 = "file2.txt";

    // Open the file in read-only mode (ignoring errors).
    let file = File::open(filename1).unwrap();
    let reader = BufReader::new(file);

    let file2 = File::open(filename2).unwrap();
    let mut reader2 = BufReader::new(file2);

    // Read the file line by line using the lines() iterator from std::io::BufRead.
    for line1 in reader.lines() {
        let line1 = line1.unwrap(); // Ignore errors.

        reader2.seek (SeekFrom::Start (0)).unwrap(); // <-- Add this line
        for line2 in reader2.by_ref().lines() {      // <-- Use by_ref here
            let line2 = line2.unwrap(); // Ignore errors.
            
            if line2 == line1 {
                println!("{}",line2)
            }

        }
    }
}

然而,这将是相当缓慢的。通过读取HashSet中的一个文件并检查另一个文件的每一行是否都在集合中,您可以使其速度更快:

代码语言:javascript
复制
use std::collections::HashSet;
use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    let filename1 = "file1.txt";
    let filename2 = "file2.txt";

    // Open the file in read-only mode (ignoring errors).
    let file = File::open(filename1).unwrap();
    let reader = BufReader::new(file);

    let file2 = File::open(filename2).unwrap();
    let reader2 = BufReader::new(file2);
    let lines2 = reader2.lines().collect::<Result<HashSet<_>, _>>().unwrap();

    // Read the file line by line using the lines() iterator from std::io::BufRead.
    for line1 in reader.lines() {
        let line1 = line1.unwrap(); // Ignore errors.

        if lines2.contains (&line1) {
            println!("{}", line1)
        }
    }
}

最后,您还可以将这两个文件读取到HashSet中,并打印出交叉点:

代码语言:javascript
复制
use std::collections::HashSet;
use std::fs::File;
use std::io::{BufRead, BufReader};

fn main() {
    let filename1 = "file1.txt";
    let filename2 = "file2.txt";

    // Open the file in read-only mode (ignoring errors).
    let file = File::open(filename1).unwrap();
    let reader = BufReader::new(file);
    let lines1 = reader.lines().collect::<Result<HashSet<_>, _>>().unwrap();

    let file2 = File::open(filename2).unwrap();
    let reader2 = BufReader::new(file2);
    let lines2 = reader2.lines().collect::<Result<HashSet<_>, _>>().unwrap();

    for l in lines1.intersection (&lines2) {
        println!("{}", l)
    }
}

作为额外的好处,最后一个解决方案将删除重复行。OTOH它不会保持行的顺序。

票数 1
EN

Stack Overflow用户

发布于 2021-04-19 19:46:01

虽然我找到了一个解决方案,但它的速度非常慢。如果谁有更好的解决方案来找到2个文件中相似的项目,请让我知道。

代码语言:javascript
复制
use std::fs::File;
use std::io::{BufRead, BufReader};



fn main() {

   let mut vec2 = findvec("file1.txt".to_string());
   let mut vec3 = &findvec("file2.txt".to_string());

   for line in vec2 {
       for line2 in vec3 {
           if line.to_string() == line2.to_string() {
               println!("{}",line.to_string());
           }
       }
   }
}

    fn findvec(filename: String) -> Vec<String> {

        // Open the file in read-only mode (ignoring errors).
        let file = File::open(filename).unwrap();
        let reader = BufReader::new(file);
    // blank vector
    let mut myvec = Vec::new();
    // Read the file line by line using the lines() iterator from std::io::BufRead.
    for (index, line) in reader.lines().enumerate() {
        let line = line.unwrap(); // Ignore errors.
        // Show the line and its number.
     
        myvec.push(line);
    }

    myvec

    
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67154863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档