You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust如何按索引访问文件行或有其他方式对比两个相邻文件行?

实现方案

这里提供两种实现方式,你可以根据文件大小选择:

方案1:边读边对比(低内存占用,适合大文件)

不需要把所有行加载到内存,仅存储上一行内容即可完成相邻对比,修改后的完整代码如下:

use std::fs::File;
use std::env;
use std::io::{self, BufReader, BufRead};

fn compare_adjacent_lines(filename: &String) -> io::Result<()> {
    let file = File::open(filename)?;
    let content = BufReader::new(file);
    let mut lines = content.lines();

    // 读取第一行作为初始对比基准
    let mut prev_line = match lines.next() {
        Some(Ok(line)) => line,
        Some(Err(e)) => return Err(e),
        None => {
            println!("文件为空,无可用对比行");
            return Ok(());
        }
    };

    // 从第二行开始逐行和上一行对比
    for (index, line) in lines.enumerate() {
        let current_line = line?;
        // index从0开始,对应对比的是第index+1行和第index+2行,即你说的索引[n]和[n+1]
        if current_line == prev_line {
            println!("第{}行和第{}行内容相同:{}", index+1, index+2, current_line);
        } else {
            println!("第{}行和第{}行内容不同:\n上一行:{}\n当前行:{}", index+1, index+2, prev_line, current_line);
        }
        // 更新基准行为当前行,用于下一轮对比
        prev_line = current_line;
    }

    Ok(())
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        eprintln!("请传入要读取的文件路径,使用方式:{} <文件名>", args[0]);
        std::process::exit(1);
    }
    let filename = &args[1];
    compare_adjacent_lines(filename).expect("读取文件出错");
}

方案2:收集所有行到Vec后按索引对比(写法直观,适合小文件)

如果你后续需要随机访问任意行的内容,可以先把所有行存入Vec,再通过索引直接对比相邻项:

use std::fs::File;
use std::env;
use std::io::{self, BufReader, BufRead};

fn compare_adjacent_lines(filename: &String) -> io::Result<()> {
    let file = File::open(filename)?;
    let content = BufReader::new(file);
    // 把所有行收集到Vec,自动处理读取错误
    let lines: Vec<String> = content.lines().collect::<Result<_, _>>()?;

    if lines.len() < 2 {
        println!("文件行数不足2行,无法完成对比");
        return Ok(());
    }

    // 按索引遍历对比n和n+1项
    for n in 0..lines.len()-1 {
        if lines[n] == lines[n+1] {
            println!("索引[{}]和索引[{}]内容相同:{}", n, n+1, lines[n]);
        } else {
            println!("索引[{}]和索引[{}]内容不同:\n索引[{}]:{}\n索引[{}]:{}", n, n+1, n, lines[n], n+1, lines[n+1]);
        }
    }

    Ok(())
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() < 2 {
        eprintln!("请传入要读取的文件路径,使用方式:{} <文件名>", args[0]);
        std::process::exit(1);
    }
    let filename = &args[1];
    compare_adjacent_lines(filename).expect("读取文件出错");
}

补充说明

  • 两种方案都额外增加了参数校验、空文件/行数不足的边界处理,避免运行时panic
  • 方案1内存占用仅和文件最长一行的长度有关,超大文件也可以正常运行;方案2需要把所有行加载到内存,更适合行数不多的小文件
  • 如果你只需要判断内容是否相同、不需要打印差异,直接替换println部分为自己的业务逻辑即可

内容的提问来源于stack exchange,提问作者456c526f

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 04:06:08