Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve File Modification and Creation Times During Zip/Unzip Operations #219

Open
mcthesw opened this issue Jul 18, 2024 · 0 comments
Open
Labels
enhancement New feature or request

Comments

@mcthesw
Copy link

mcthesw commented Jul 18, 2024

Is your feature request related to a problem? Please describe.
When using the zip crate to compress and decompress files, the original modification and creation times of the files are not preserved. This causes issues in applications where file order or timestamp accuracy is crucial, such as game save managers or backup utilities.

Describe the solution you'd like
I propose adding functions or options to both compress and decompress operations that would preserve the original file modification and creation times. These functions should work across different platforms (Windows, Linux, macOS) and handle both files and folders recursively.

This would be nice:

// These functions would automatically handle the preservation of original file timestamps
// without requiring manual intervention.

// Compress
zip.start_file(file_name, SimpleFileOptions::default().with_original_time()); // These functions would automatically handle the preservation of original file timestamps without requiring manual intervention.

// Decompress
zip.extract_with_time(target);

Describe alternatives you've considered
Currently, I'm using SimpleFileOptions::last_modified_time() for compression and set_modified for decompression. I also have tried crate fs_set_times to set modified time for folders. However, this approach is not ideal as it requires additional dependencies and doesn't provide a unified solution within the zip crate.

// Compress
let mut original_file = File::open(&file_path).unwrap();
let last_modify_time = original_file.metadata().unwrap().modified().unwrap();
let last_modify_time = DateTime::<Local>::from(last_modify_time).naive_local();

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

// After decompression, I need to set the time mannualy
let last_modified = zip
    .by_name(original_path.file_name().unwrap().to_str().unwrap())
    .unwrap()
    .last_modified()
    .unwrap();
let last_modified = 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);
OpenOptions::new()
    .write(true)
    .open(&original_path)
    .unwrap()
    .set_modified(last_modified)
    .unwrap();

This method works for files, but I don't know how to handle folders.

Additional context
I suspect that my lack of familiarity with this library or time-related types might be contributing to the issue. Prior to this, I posted a related question on Stack Overflow, but so far there hasn't been a suitable solution. I'm including the link to that question here for reference: Link

I believe this feature would greatly enhance the functionality of the zip crate and benefit many users. Thank you for considering this request.

@mcthesw mcthesw added the enhancement New feature or request label Jul 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant