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
相关产品推荐
相关产品推荐

