Pregunta

I want to decompress a large folder in ZIP format with nested subdirectories in a directory that already exists. The files inside the ZIP folder can exist in the decompressed directory. I need to keep the previous files only when the date of that file is newer than the date of the file in the ZIP folder. If the file in the ZIP is newer, then I want to overwrite it.

There is some good strategy for doing this? I already checked truezip and zip4j, but I can't find the option (the best option for me so far is modifying the zip4j sources, but it should be a better way.

P.S. If I haven't explained this correctly, please feel free to ask. English is not my native language and I could have expressed anything wrong..

Thanks.

¿Fue útil?

Solución

With Zip4j, this is how it can be done:

import java.io.File;
import java.util.Date;
import java.util.List;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.util.Zip4jUtil;


public class ExtractWithoutOverwriting {

    public static void main(String[] args) {

        try {
            String outputPath = "yourOutputPath";
            ZipFile zipFile = new ZipFile(new File("yourZipFile.zip"));
            if (zipFile.isEncrypted()) {
                zipFile.setPassword("yourPassword".toCharArray());
            }

            @SuppressWarnings("unchecked")
            List<FileHeader> fileHeaders = zipFile.getFileHeaders();

            for (FileHeader fileHeader : fileHeaders) {
                if (fileHeader.isDirectory()) {
                    File file = new File(outputPath + System.getProperty("file.separator") + fileHeader.getFileName());
                    file.mkdirs();
                } else {
                    if (canWrite(outputPath, fileHeader)) {
                        System.out.println("Writing file: " + fileHeader.getFileName());
                        zipFile.extractFile(fileHeader, outputPath);
                    } else {
                        System.out.println("Not writing file: " + fileHeader.getFileName());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static boolean canWrite(String outputPath, FileHeader fileHeader) {
        File file = new File(outputPath + System.getProperty("file.separator") + fileHeader.getFileName());
        //time stamps are stored in dos format in a zip file
        //convert it to java format
        long lastModifiedFromZip = Zip4jUtil.dosToJavaTme(fileHeader.getLastModFileTime());

        //If the file exists, it can be overwritten only if the file in the destination path
        //is newer than the one in the zip file
        return !(file.exists() && isLastModifiedDateFromFileNewer(file.lastModified(), lastModifiedFromZip));
    }

    public static boolean isLastModifiedDateFromFileNewer(long lastModifiedFromFile, long lastModifiedFromZip) {
        Date lastModifiedDateFromFile = new Date(lastModifiedFromFile);
        Date lastModifiedDateFromZip = new Date(lastModifiedFromZip);

        return lastModifiedDateFromFile.after(lastModifiedDateFromZip);
    }

}

What we do here is:

  1. Create a new instance of the ZipFile
  2. If the zip file is encrypted, set a password
  3. Loop over all files in the zip file
  4. Check if a file with this name exists in the output path and if this file's last modification time is "newer" than the one in the zip file. This check is done in the method: canWrite()

This code is not completely tested, but I hope it gives you an idea of a solution.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top