Skip to content

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

Open
@mcthesw

Description

@mcthesw

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions