Création d'une archive zip en Java


J'ai un fichier créé par le programme 7zip. J'ai utilisé la méthode deflate pour la compresser. Maintenant, je veux créer la même archive (avec le même MD5sum) dans java. Lorsque je crée un fichier zip, j'ai utilisé l'algorithme que j'ai trouvé sur Internet par exemple http://www.kodejava.org/examples/119.html mais lorsque j'ai créé un fichier zip avec cette méthode, la taille compressée est supérieure à la taille du fichier non compressé, alors que se passe-t-il? Ce n'est pas une compression très utile. Alors, comment je peux créer fichier zip qui est exactement le même que le fichier zip que j'ai créé avec 7zip programme ? Si cela aide, j'ai toutes les informations sur le fichier zip que j'ai créé dans le programme 7zip.

Author: ROMANIA_engineer, 2011-01-23

7 answers

// simplified code for zip creation in java

import java.io.*;
import java.util.zip.*;

public class ZipCreateExample {

    public static void main(String[] args) throws Exception {

        // input file 
        FileInputStream in = new FileInputStream("F:/sometxt.txt");

        // out put file 
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream("F:/tmp.zip"));

        // name the file inside the zip  file 
        out.putNextEntry(new ZipEntry("zippedjava.txt")); 

        // buffer size
        byte[] b = new byte[1024];
        int count;

        while ((count = in.read(b)) > 0) {
            out.write(b, 0, count);
        }
        out.close();
        in.close();
    }
}
 58
Author: Nishanth Thomas, 2016-08-04 08:07:34

Juste pour clarifier, vous avez utilisé l'algorithme ZIP dans 7zip pour votre original? En outre, 7zip prétend avoir un taux de compression 2-10% meilleur que les autres fournisseurs. Je suppose que l'algorithme ZIP intégré à Java n'est pas aussi optimisé que celui de 7zip. Votre mieux est d'appeler 7zip à partir de la ligne de commande si vous voulez un fichier compressé similaire.

Essayez-vous de décompresser un fichier ZIP, de modifier un fichier, puis de le compresser à nouveau pour qu'il ait le même hachage MD5? Hachage sont destinés à vous empêcher de le faire.

 5
Author: Andrew T Finnell, 2011-01-23 12:55:16

ZipOutputStream a peu de méthodes pour régler la compression:

La méthode publique void setMethod (méthode int)

Définit la méthode de compression par défaut pour les entrées suivantes. Ce défaut sera utilisé chaque fois que la compression la méthode n'est pas spécifiée pour un entrée de fichier ZIP individuel, et est initialement défini sur DÉGONFLÉ.

Public void setLevel (niveau int)

Définit le niveau de compression pour entrées suivantes qui sont DÉGONFLER. Le paramètre par défaut est DEFAULT_COMPRESSION. niveau-le niveau de compression (0-9)

Lorsque vous ajoutez après quelque chose comme:

ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(target));
zos.setMethod( ZipOutputStream.DEFLATED );
zos.setLevel( 5 );
...

N'améliore-t-il pas votre compression?

 5
Author: Maxym, 2011-01-23 13:00:21

Voici une fonction que vous passez le chemin absolu, il va créer un fichier zip avec le même nom que le répertoire (sous lequel vous voulez zip de tous les sous-dossiers et fichiers, tout !!) et renvoie true en cas de succès et false en cas d'exception.

public class FileUtil { 
final static int BUFFER = 2048;
private static Logger log = Logger.getLogger(FileUtil.class);

      public static boolean createZipArchive(String srcFolder) {

    try {
        BufferedInputStream origin = null;



        FileOutputStream    dest = new FileOutputStream(new File(srcFolder+ ".zip"));

        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
        byte data[] = new byte[BUFFER];

        File subDir = new File(srcFolder);
        String subdirList[] = subDir.list();
        for(String sd:subdirList)
        {
                // get a list of files from current directory
                File f = new File(srcFolder+"/"+sd);
                if(f.isDirectory())
                {
                    String files[] = f.list();

                    for (int i = 0; i < files.length; i++) {
                        System.out.println("Adding: " + files[i]);
                        FileInputStream fi = new FileInputStream(srcFolder  + "/"+sd+"/" + files[i]);
                        origin = new BufferedInputStream(fi, BUFFER);
                        ZipEntry entry = new ZipEntry(sd +"/"+files[i]);
                        out.putNextEntry(entry);
                        int count;
                        while ((count = origin.read(data, 0, BUFFER)) != -1) {
                            out.write(data, 0, count);
                            out.flush();
                        }

                    }
                }
                else //it is just a file
                {
                    FileInputStream fi = new FileInputStream(f);
                    origin = new BufferedInputStream(fi, BUFFER);
                    ZipEntry entry = new ZipEntry(sd);
                    out.putNextEntry(entry);
                    int count;
                    while ((count = origin.read(data, 0, BUFFER)) != -1) {
                        out.write(data, 0, count);
                        out.flush();
                    }

                }
        }
        origin.close();
        out.flush();
        out.close();
    } catch (Exception e) {
        log.info("createZipArchive threw exception: " + e.getMessage());        
        return false;

    }


    return true;
}   
  }
 4
Author: Steer360, 2013-05-06 13:56:48

Pour générer deux fichiers zip identiques (y compris md5sum identiques) à partir du même fichier source, je recommanderais d'utiliser le même utilitaire zip-soit toujours utiliser le même programme Java, soit toujours utiliser 7zip.

L'utilitaire 7zip par exemple a beaucoup d'options-dont beaucoup sont simplement des valeurs par défaut qui peuvent être personnalisées (ou diffèrent entre les versions?) -- et toute implémentation Java zip devrait également définir ces options explicitement. Si votre application Java peut simplement invoquer un programme externe "7z", vous obtiendrez probablement de meilleures performances de toute façon qu'une implémentation Java zip personnalisée. (Ceci est également un bon exemple d'un problème de réduction de carte où vous pouvez facilement mettre à l'échelle l'implémentation.)

, Mais le principal problème que vous rencontrerez si vous avez un serveur fichier zip généré et côté client fichier zip généré est que le fichier zip magasins deux choses en plus de simplement le fichier d'origine: (1) le nom de fichier, et (2) l'horodatage du fichier. Si l'une de ces ont modifié, le fichier zip résultant aura un md5sum différent:

$ ls tst1/
foo.tar

$ cp -r tst1 tst2

$ ( cd tst1; zip foo.zip foo.tar )  ; ( cd tst2; zip foo.zip foo.tar )   ; md5sum tst?/foo.zip
updating: foo.tar (deflated 20%)
updating: foo.tar (deflated 20%)
359b82678a2e17c1ddbc795ceeae7b60  tst1/foo.zip
b55c33c0414ff987597d3ef9ad8d1d08  tst2/foo.zip

Mais, en utilisant " cp-p "(conserver l'horodatage):

$ cp -p -r tst1 tst2

$ ( cd tst1; zip foo.zip foo.tar )  ; ( cd tst2; zip foo.zip foo.tar )   ; md5sum tst?/foo.zip
updating: foo.tar (deflated 20%)
updating: foo.tar (deflated 20%)
359b82678a2e17c1ddbc795ceeae7b60  tst1/foo.zip
359b82678a2e17c1ddbc795ceeae7b60  tst2/foo.zip

Vous trouverez le même problème avec des noms de fichiers et des chemins différents, même lorsque les fichiers à l'intérieur du zip sont identiques.

 1
Author: michael, 2011-12-14 11:54:35
package comm;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;*emphasized text*
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Zip1 {
      public static void main( String[] args )
        {
            byte[] buffer = new byte[1024];

            try{

                File f= new  File("E:\\");
                f.mkdirs();
                File origFile= new File(f,"MyZipFile2.zip");
                FileOutputStream fos = new FileOutputStream(origFile);

                ZipOutputStream zos = new ZipOutputStream(fos);
                ZipEntry ze= new ZipEntry("test.pdf");
                zos.putNextEntry(ze);
                FileInputStream in = new FileInputStream("D:\\Test.pdf");

                int len;
                while ((len = in.read(buffer)) > 0) {
                    zos.write(buffer, 0, len);
                }

                in.close();
                zos.closeEntry();

                //remember close it
                zos.close();

                System.out.println("Done");

            }catch(IOException ex){
               ex.printStackTrace();
            }
        }
}
 0
Author: vamsi, 2013-07-31 12:14:56

Veuillez trouver dans le code ci-dessous ayant les fonctionnalités de zip et décompressez - . Espérons qu'il peut aider quelqu'un.

package com.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


/**
 * @author dinesh.lomte
 *
 */
public class ZipUtil {

    /**
     * 
     * @param source
     * @param destination
     */
    public static void unZip(String source, String destination) {

        String method = "unZip(String source, String destination)";
        ZipInputStream zipInputStream = null;
        try {
            // Creating the ZipInputStream instance from the source file
            zipInputStream = new ZipInputStream(new FileInputStream(source));
            // Getting the zipped file list entry
            ZipEntry zipEntry = zipInputStream.getNextEntry();
            // Iterating through the file list entry
            while (zipEntry != null) {
                String fileName = zipEntry.getName();
                File file = new File(new StringBuilder(destination)
                    .append(File.separator)
                    .append(AppUtil.getFileNameWithoutExtension(
                            AppUtil.getNameFromPath(source)))
                    .append(File.separator).append(fileName).toString());                
                // Creating non existing folders to avoid any FileNotFoundException 
                // for compressed folder
                new File(file.getParent()).mkdirs();
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                byte[] buffer = new byte[1024];
                int length;
                while ((length = zipInputStream.read(buffer)) > 0) {
                    fileOutputStream.write(buffer, 0, length);
                }
                fileOutputStream.close();
                zipEntry = zipInputStream.getNextEntry();
            }
        } catch (IOException iOException) {
            System.out.println("Failed to unzip the ''{0}'' file located in ''{1}'' folder. Due to, {2}");

        } finally {
            // Validating if zipInputStream instance in not null
            if (zipInputStream != null) {
                try {
                    zipInputStream.closeEntry();
                    zipInputStream.close();
                } catch (IOException iOException) {                 
                }
            }
        }
    }

    /**
     * Traverse a directory from the source folder location and get all files,
     * and add the file into files list.
     *
     * @param node
     */
    public static void generateFileList(
            String source, File node, List<String> files) {     
        // Validating if the node is a file
        if (node.isFile()) {
            files.add(generateZipEntry(
                    source, node.getPath().toString()));
        }
        // Validating if the node is a directory
        if (node.isDirectory()) {
            String[] subNote = node.list();
            for (String filename : subNote) {
                generateFileList(source, new File(node, filename), files);
            }
        }
    }

    /**
     * Format the file path to zip
     * @param source
     * @param file
     * @return
     */
    private static String generateZipEntry(String source, String file) {
        return file.substring(source.length(), file.length());
    }

    /**
     * 
     * @param source
     * @param destination
     */
    public static void zip(String source, String destination) {

        String method = "zip(String source, String destination)";
        ZipOutputStream zipOutputStream = null;        
        try {            
            // Creating the zipOutputStream instance
            zipOutputStream = new ZipOutputStream(
                    new FileOutputStream(destination));
            List<String> files = new ArrayList<>();
            generateFileList(source, new File(source), files);
            // Iterating the list of file(s) to zip/compress
            for (String file : files) {
                // Adding the file(s) to the zip
                ZipEntry zipEntry = new ZipEntry(file);
                zipOutputStream.putNextEntry(zipEntry);
                FileInputStream fileInputStream = new FileInputStream(
                        new StringBuilder(source).append(File.separator)
                        .append(file).toString());
                int length;
                byte[] buffer = new byte[1024];
                while ((length = fileInputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, length);
                }                
                // Closing the fileInputStream instance
                fileInputStream.close();
                // De-allocating the memory by assigning the null value
                fileInputStream = null;
            }
        } catch (IOException iOException) {
            System.out.println("Failed to zip the file(s) located in ''{0}'' folder. Due to, {1}");
        } finally {
            // Validating if zipOutputStream instance in not null
            if (zipOutputStream != null) {
                try {
                    zipOutputStream.closeEntry();
                    zipOutputStream.close();
                } catch (IOException iOException) {
                }
            }
        }
    }
}
 0
Author: Dinesh Lomte, 2017-03-30 13:43:13