在Rust中判断两个文件内容是否相同
2023-03-28 22:11:19 +08 字数:542 标签: Rust在Rust中判断两个文件内容是否相同,意外地并不好写。
这里记录了一个函数,未来用到时复制。 并且还展示了一些文件操作,以便参考。
一个函数 ¶
use std::{
fs::File,
io::BufReader,
path::Path,
};
fn is_same_file(one: impl AsRef<Path>, another: impl AsRef<Path>) -> bool {
if let (Ok(file0), Ok(file1)) = (File::open(one), File::open(another)) {
let mut reader0 = BufReader::new(file0);
let mut reader1 = BufReader::new(file1);
let mut buf0 = [0u8; 256];
let mut buf1 = [0u8; 256];
while let (Ok(n0), Ok(n1)) = (reader0.read(&mut buf0), reader1.read(&mut buf1)) {
if n0 != n1 {
return false;
}
if n0 == 0 {
return true;
}
if buf0 != buf1 {
return false;
}
}
}
return false;
}
以上代码,有几个要点,基本已做到了比较极致的优化:
- 不存在,或读不了的文件,直接返回
false
。 - 判断内容的buffer仅有256的长度(可调),内存开销小,
false
返回更快。 - 先判断长度、再判断内容。
BufReader::read
在结束时,长度会小于256。 如果读出长度n0 != n1
,则说明其中一个提前结束。 - 当两个文件内容都比对完后,则返回
true
。 一个已经读完的文件,再读则长度为0。 如果n0 == n1 == 0
,则说明两个文件已经比对完成,完全相等。
一个库 ¶
如果不介意为了这个简单功能,加一个库的话,可以用same-file。
use same_file::is_same_file;
fn main() {
assert!(is_same_file("/bin/sh", "/usr/bin/sh").unwrap());
}
其它 ¶
一个文件,除了文件内容,还有文件信息,如文件名、权限、修改时间等。 这些在以上方案中,都不在比对范围内,有需要则必须单独比对。
此外,还有一些间接比对文件内容的方案,比方说,比较两个文件的SHA256。 这效率不高,但在某些特殊场景,可能会更方便。