在 Rust 中压缩和解压缩时如何保留文件修改时间?

问题描述 投票:0回答:1

我正在使用 Tauri 和 Rust 开发一个游戏保存管理器。该工具使用 zip crate 压缩和解压缩游戏保存。然而,用户报告说,该工具扰乱了游戏中保存文件的顺序,该顺序是根据上次修改时间对保存进行排序的。发生这种情况是因为在恢复保存时,文件被赋予当前系统时间而不是其原始修改时间。我尝试在压缩过程中保留原始修改时间,但在解压缩过程中尝试恢复这些时间时遇到了困难,特别是在 Windows 11 上。

压缩文件时,我使用

last_modified_time
SimpleFileOptions
选项将原始修改时间存储在zip文件中。这似乎工作正常,因为我可以验证 zip 文件中存储的时间是否正确。

let mut original_file = File::open(&unit_path)?;
let last_modify_time = original_file.metadata()?.modified()?;
let last_modify_time =
    chrono::DateTime::<Local>::from(last_modify_time).naive_local();

let mut buf = vec![];
original_file.read_to_end(&mut buf)?;
zip.start_file(
    unit_path
        .file_name()
        .ok_or(BackupFileError::NonePathError)?
        .to_str()
        .ok_or(BackupFileError::NonePathError)?,
    SimpleFileOptions::default()
        .compression_method(zip::CompressionMethod::Bzip2)
        .last_modified_time(last_modify_time.try_into().unwrap()),
)?;

此方法可以正确地将时间存储在 zip 文件中。这个方法可靠吗?对于文件夹,我将此过程递归地应用于文件夹内的文件,但我不确定这是否是正确的方法。

解压缩时,我尝试从 zip 文件中读取存储的修改时间,并使用

File::set_modified()
将其设置在提取的文件上。但是,这会导致 Windows 11 上出现“权限被拒绝”错误。

let option = fs_extra::file::CopyOptions::new().overwrite(true);
let last_modified = zip
    .by_name(original_path.file_name().unwrap().to_str().unwrap())
    .unwrap()
    .last_modified()
    .unwrap();
let last_modified = chrono::NaiveDateTime::try_from(last_modified)
    .unwrap()
    .and_local_timezone(Local)
    .unwrap()
    .timestamp();
let last_modified =
    UNIX_EPOCH + std::time::Duration::from_secs(last_modified as u64);
File::open(&original_path)
    .unwrap()
    .set_modified(last_modified)
    .unwrap();  // this line panic! "Permission denied" 
fs_extra::file::move_file(&original_path, &unit_path, &option)?;

我希望这些步骤能够在整个压缩和解压缩过程中保留文件的原始修改时间。相反,虽然我可以成功存储时间,但由于权限问题,我无法在提取文件时应用它们。我不确定我的方法是否正确,或者是否有更有效的方法来处理这种情况下的文件元数据。

顺便说一句,当我在 Windows 上进行开发时,我的目标是让程序也能在 Linux 或 macOS 上运行。因此,我正在寻找解决此问题的跨平台解决方案。

windows rust file-io zip tauri
1个回答
0
投票

我正在编写一个用于处理

.docx
文件的库,其中内部元数据不会被搞乱。

  • SimpleFileOptions
    还不够,所以您可能需要 一个帮手 返回
    FileOptions
    。我的是从
    zip::ZipWriter::raw_copy_file_rename
    复制的。

  • 如果您读取文件by_index,内部索引顺序也可以保留。

© www.soinside.com 2019 - 2024. All rights reserved.