mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-05 17:44:52 +01:00
io/fs: do not replace files with unchanged contents
Do not update file timestamps when contents have not actually changed.
This commit is contained in:
parent
cb791f48e9
commit
e18d4cea82
1 changed files with 28 additions and 3 deletions
31
src/io/fs.rs
31
src/io/fs.rs
|
@ -1,6 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::{BufWriter, Write},
|
io::{BufReader, BufWriter, Read, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,19 +41,44 @@ where
|
||||||
.with_context(|| format!("Failed to write file {}", path.display()))
|
.with_context(|| format!("Failed to write file {}", path.display()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn equal(path1: &Path, path2: &Path) -> Result<bool> {
|
||||||
|
let mut file1 = BufReader::new(
|
||||||
|
fs::File::open(path1)
|
||||||
|
.with_context(|| format!("Failed to open file {}", path1.display()))?,
|
||||||
|
)
|
||||||
|
.bytes();
|
||||||
|
let mut file2 = BufReader::new(
|
||||||
|
fs::File::open(path2)
|
||||||
|
.with_context(|| format!("Failed to open file {}", path2.display()))?,
|
||||||
|
)
|
||||||
|
.bytes();
|
||||||
|
|
||||||
|
Ok(loop {
|
||||||
|
match (file1.next().transpose()?, file2.next().transpose()?) {
|
||||||
|
(Some(b1), Some(b2)) if b1 == b2 => continue,
|
||||||
|
(None, None) => break true,
|
||||||
|
_ => break false,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_with_tmpfile<T, F>(path: &Path, f: F) -> Result<T>
|
pub fn create_with_tmpfile<T, F>(path: &Path, f: F) -> Result<T>
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut BufWriter<File>) -> Result<T>,
|
F: FnOnce(&mut BufWriter<File>) -> Result<T>,
|
||||||
{
|
{
|
||||||
let tmp_path = tmpfile_name(path);
|
let tmp_path = tmpfile_name(path);
|
||||||
|
let mut cleanup = true;
|
||||||
|
|
||||||
let ret = (|| {
|
let ret = (|| {
|
||||||
let ret = create(&tmp_path, f)?;
|
let ret = create(&tmp_path, f)?;
|
||||||
rename(&tmp_path, path)?;
|
if !matches!(equal(path, &tmp_path), Result::Ok(true)) {
|
||||||
|
rename(&tmp_path, path)?;
|
||||||
|
cleanup = false;
|
||||||
|
}
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
})();
|
})();
|
||||||
|
|
||||||
if ret.is_err() {
|
if cleanup {
|
||||||
let _ = fs::remove_file(&tmp_path);
|
let _ = fs::remove_file(&tmp_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue