wake-up-neo.com

wie man einen Ordner selbst mit Java zippt

Angenommen, ich habe die folgende Verzeichnisstruktur. 

D:\reports\january\

Im Januar gibt es zwei Excel-Dateien, die mit A.xls und B.xls bezeichnet werden. Es gibt viele Stellen, an denen geschrieben wurde, wie Dateien mit Java.util.Zip komprimiert werden. Ich möchte jedoch den Januar-Ordner selbst in den Berichtsordner packen, sodass sowohl januar als auch january.Zip in Berichten vorhanden sind. (Das heißt, wenn ich die january.Zip-Datei entpacke, sollte ich den january-Ordner) erhalten. 

Kann mir jemand bitte den Code geben, um dies mit Java.util.Zip zu tun. Bitte lassen Sie mich wissen, ob dies mit anderen Bibliotheken einfacher ist. 

Danke vielmals...

55
mukund

Es kann leicht gelöst werden, indem das Paket Java.util.Zip keine zusätzlichen Jar-Dateien benötigt 

Kopieren Sie einfach den folgenden Code und run it mit Ihrer IDE 

//Import all needed packages
package general;
import Java.io.File;
import Java.io.FileInputStream;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.util.ArrayList;
import Java.util.List;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipOutputStream;

public class ZipUtils {

    private List <String> fileList;
    private static final String OUTPUT_Zip_FILE = "Folder.Zip";
    private static final String SOURCE_FOLDER = "D:\\Reports"; // SourceFolder path

    public ZipUtils() {
        fileList = new ArrayList < String > ();
    }

    public static void main(String[] args) {
        ZipUtils appZip = new ZipUtils();
        appZip.generateFileList(new File(SOURCE_FOLDER));
        appZip.zipIt(OUTPUT_Zip_FILE);
    }

    public void zipIt(String zipFile) {
        byte[] buffer = new byte[1024];
        String source = new File(SOURCE_FOLDER).getName();
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        try {
            fos = new FileOutputStream(zipFile);
            zos = new ZipOutputStream(fos);

            System.out.println("Output to Zip : " + zipFile);
            FileInputStream in = null;

            for (String file: this.fileList) {
                System.out.println("File Added : " + file);
                ZipEntry ze = new ZipEntry(source + File.separator + file);
                zos.putNextEntry(ze);
                try {
                    in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
                    int len;
                    while ((len = in .read(buffer)) > 0) {
                        zos.write(buffer, 0, len);
                    }
                } finally {
                    in.close();
                }
            }

            zos.closeEntry();
            System.out.println("Folder successfully compressed");

        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                zos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void generateFileList(File node) {
        // add file only
        if (node.isFile()) {
            fileList.add(generateZipEntry(node.toString()));
        }

        if (node.isDirectory()) {
            String[] subNote = node.list();
            for (String filename: subNote) {
                generateFileList(new File(node, filename));
            }
        }
    }

    private String generateZipEntry(String file) {
        return file.substring(SOURCE_FOLDER.length() + 1, file.length());
    }
}

Siehe mkyong .. Ich habe den Code für die Anforderung der aktuellen Frage geändert

48
kark

Haben Sie versucht, Zeroturnaround Zip library? Es ist wirklich ordentlich! Ein ZIP-Ordner ist nur ein Einzeiler:

ZipUtil.pack(new File("D:\\reports\\january\\"), new File("D:\\reports\\january.Zip"));

(Dank an Oleg Šelajev für das Beispiel)

81
Petro Semeniuk

Hier ist das Java 8+ Beispiel:

public static void pack(String sourceDirPath, String zipFilePath) throws IOException {
    Path p = Files.createFile(Paths.get(zipFilePath));
    try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p))) {
        Path pp = Paths.get(sourceDirPath);
        Files.walk(pp)
          .filter(path -> !Files.isDirectory(path))
          .forEach(path -> {
              ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
              try {
                  zs.putNextEntry(zipEntry);
                  Files.copy(path, zs);
                  zs.closeEntry();
            } catch (IOException e) {
                System.err.println(e);
            }
          });
    }
}
62

Hier ist eine recht knappe Java 7+ -Lösung, die rein auf Vanilla JDK-Klassen basiert und keine Bibliotheken von Drittanbietern benötigt:

public static void pack(final Path folder, final Path zipFilePath) throws IOException {
    try (
            FileOutputStream fos = new FileOutputStream(zipFilePath.toFile());
            ZipOutputStream zos = new ZipOutputStream(fos)
    ) {
        Files.walkFileTree(folder, new SimpleFileVisitor<Path>() {
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                zos.putNextEntry(new ZipEntry(folder.relativize(file).toString()));
                Files.copy(file, zos);
                zos.closeEntry();
                return FileVisitResult.CONTINUE;
            }

            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                zos.putNextEntry(new ZipEntry(folder.relativize(dir).toString() + "/"));
                zos.closeEntry();
                return FileVisitResult.CONTINUE;
            }
        });
    }
}

Es kopiert alle Dateien in folder, einschließlich leerer Verzeichnisse, und erstellt ein Zip-Archiv unter zipFilePath.

31
jjst

Java 7+, commons.io

public final class ZipUtils {

    public static void zipFolder(final File folder, final File zipFile) throws IOException {
        zipFolder(folder, new FileOutputStream(zipFile));
    }

    public static void zipFolder(final File folder, final OutputStream outputStream) throws IOException {
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
            processFolder(folder, zipOutputStream, folder.getPath().length() + 1);
        }
    }

    private static void processFolder(final File folder, final ZipOutputStream zipOutputStream, final int prefixLength)
            throws IOException {
        for (final File file : folder.listFiles()) {
            if (file.isFile()) {
                final ZipEntry zipEntry = new ZipEntry(file.getPath().substring(prefixLength));
                zipOutputStream.putNextEntry(zipEntry);
                try (FileInputStream inputStream = new FileInputStream(file)) {
                    IOUtils.copy(inputStream, zipOutputStream);
                }
                zipOutputStream.closeEntry();
            } else if (file.isDirectory()) {
                processFolder(file, zipOutputStream, prefixLength);
            }
        }
    }
}
10
Tony BenBrahim

Ich benutze normalerweise eine Hilfsklasse, die ich einmal für diese Aufgabe geschrieben habe:

import Java.util.Zip.*;
import Java.io.*;

public class ZipExample {
    public static void main(String[] args){
        ZipHelper zippy = new ZipHelper();
        try {
            zippy.zipDir("folderName","test.Zip");
        } catch(IOException e2) {
            System.err.println(e2);
        }
    }
}

class ZipHelper  
{
    public void zipDir(String dirName, String nameZipFile) throws IOException {
        ZipOutputStream Zip = null;
        FileOutputStream fW = null;
        fW = new FileOutputStream(nameZipFile);
        Zip = new ZipOutputStream(fW);
        addFolderToZip("", dirName, Zip);
        Zip.close();
        fW.close();
    }

    private void addFolderToZip(String path, String srcFolder, ZipOutputStream Zip) throws IOException {
        File folder = new File(srcFolder);
        if (folder.list().length == 0) {
            addFileToZip(path , srcFolder, Zip, true);
        }
        else {
            for (String fileName : folder.list()) {
                if (path.equals("")) {
                    addFileToZip(folder.getName(), srcFolder + "/" + fileName, Zip, false);
                } 
                else {
                     addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, Zip, false);
                }
            }
        }
    }

    private void addFileToZip(String path, String srcFile, ZipOutputStream Zip, boolean flag) throws IOException {
        File folder = new File(srcFile);
        if (flag) {
            Zip.putNextEntry(new ZipEntry(path + "/" +folder.getName() + "/"));
        }
        else {
            if (folder.isDirectory()) {
                addFolderToZip(path, srcFile, Zip);
            }
            else {
                byte[] buf = new byte[1024];
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                Zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
                while ((len = in.read(buf)) > 0) {
                    Zip.write(buf, 0, len);
                }
            }
        }
    }
}
7
halex

Ich würde Apache Ant verwenden, das eine API zum Aufrufen von Tasks aus Java-Code anstatt aus einer XML-Builddatei enthält.

Project p = new Project();
p.init();
Zip zip = new Zip();
Zip.setProject(p);
Zip.setDestFile(zipFile); // a Java.io.File for the Zip you want to create
Zip.setBasedir(new File("D:\\reports"));
Zip.setIncludes("january/**");
Zip.perform();

Hier sage ich es, um vom D:\reports Basisverzeichnis zu starten und den january Ordner und alles darin zu packen. Die Pfade in der resultierenden Zip-Datei sind mit den ursprünglichen Pfaden relativ zu D:\reports identisch, daher enthalten sie das Präfix january.

4
Ian Roberts

Erweitertes Java 8+-Beispiel (Aus Antwort von Nikita Koksharov )

public static void pack(String sourceDirPath, String zipFilePath) throws IOException {
    Path p = Files.createFile(Paths.get(zipFilePath));
    Path pp = Paths.get(sourceDirPath);
    try (ZipOutputStream zs = new ZipOutputStream(Files.newOutputStream(p));
        Stream<Path> paths = Files.walk(pp)) {
        paths
          .filter(path -> !Files.isDirectory(path))
          .forEach(path -> {
              ZipEntry zipEntry = new ZipEntry(pp.relativize(path).toString());
              try {
                  zs.putNextEntry(zipEntry);
                  Files.copy(path, zs);
                  zs.closeEntry();
            } catch (IOException e) {
                System.err.println(e);
            }
          });
    }
}

Files.walk wurde in try with resources-Block eingeschlossen, sodass der Stream geschlossen werden kann. Dies behebt Blockerprobleme, die durch SonarQube..__ identifiziert wurden. Vielen Dank @Matt Harrison für das Zeigen.

3
Abdul Rauf

Versuche dies:

 import Java.io.File;

 import Java.io.FileInputStream;

 import Java.io.FileOutputStream;

 import Java.util.Zip.ZipEntry;

 import Java.util.Zip.ZipOutputStream;


  public class Zip {

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

    zipFolder("D:\\reports\\january", "D:\\reports\\january.Zip");

  }

  static public void zipFolder(String srcFolder, String destZipFile) throws Exception {
    ZipOutputStream Zip = null;
    FileOutputStream fileWriter = null;
    fileWriter = new FileOutputStream(destZipFile);
    Zip = new ZipOutputStream(fileWriter);
    addFolderToZip("", srcFolder, Zip);
    Zip.flush();
    Zip.close();
  }
  static private void addFileToZip(String path, String srcFile, ZipOutputStream Zip)
      throws Exception {
    File folder = new File(srcFile);
    if (folder.isDirectory()) {
      addFolderToZip(path, srcFile, Zip);
    } else {
      byte[] buf = new byte[1024];
      int len;
      FileInputStream in = new FileInputStream(srcFile);
      Zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
      while ((len = in.read(buf)) > 0) {
        Zip.write(buf, 0, len);
      }
    }
  }

  static private void addFolderToZip(String path, String srcFolder, ZipOutputStream Zip)
      throws Exception {
    File folder = new File(srcFolder);

    for (String fileName : folder.list()) {
      if (path.equals("")) {
        addFileToZip(folder.getName(), srcFolder + "/" + fileName, Zip);
      } else {
        addFileToZip(path + "/" + folder.getName(), srcFolder + "/" +   fileName, Zip);
      }
    }
  }



   }
2
Denis

Java 6 +

import Java.io.*;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipOutputStream;

public class Zip {

    private static final FileFilter FOLDER_FILTER = new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isDirectory();
        }
    };

    private static final FileFilter FILE_FILTER = new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.isFile();
        }
    };


    private static void compress(File file, ZipOutputStream outputStream, String path) throws IOException {

        if (file.isDirectory()) {
            File[] subFiles = file.listFiles(FILE_FILTER);
            if (subFiles != null) {
                for (File subFile : subFiles) {
                    compress(subFile, outputStream, new File(path, subFile.getName()).getAbsolutePath());
                }
            }
            File[] subDirs = file.listFiles(FOLDER_FILTER);
            if (subDirs != null) {
                for (File subDir : subDirs) {
                    compress(subDir, outputStream, new File(path, subDir.getName()).getAbsolutePath());
                }
            }
        } else if (file.exists()) {
            outputStream.putNextEntry(new ZipEntry(path));
            FileInputStream inputStream = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) >= 0) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.closeEntry();
        }
    }

    public static void compress(String dirPath, String zipFilePath) throws IOException {
        File file = new File(dirPath);
        final ZipOutputStream outputStream = new ZipOutputStream(new FileOutputStream(zipFilePath));
        compress(file, outputStream, "/");
        outputStream.close();
    }

}
1
Dillion Wang

Mit Zip4j können Sie dies einfach tun

ZipFile zipfile = new ZipFile(new File("D:\\reports\\january\\filename.Zip"));
zipfile.addFolder(new File("D:\\reports\\january\\"));

Es wird Ihren Ordner und alles darin archivieren.

Verwenden Sie die .extractAll -Methode, um alles herauszufinden:

zipfile.extractAll("D:\\destination_directory");
1
svarog

Ich fand diese Lösung perfekt für mich. Benötigt keine Drittanbieter-API

'test' ist eigentlich ein Ordner, der viele Dateien enthält.

String folderPath= "C:\Users\Desktop\test";
String zipPath = "C:\Users\Desktop\test1.Zip";

private boolean zipDirectory(String folderPath, String zipPath) throws IOException{

        byte[] buffer = new byte[1024];
        FileInputStream fis = null;
        ZipOutputStream zos = null;

        try{
            zos = new ZipOutputStream(new FileOutputStream(zipPath));
            updateSourceFolder(new File(folderPath));

            if (sourceFolder == null) {
                zos.close();
                return false;
            }
            generateFileAndFolderList(new File(folderPath));

            for (String unzippedFile: fileList) {
                System.out.println(sourceFolder + unzippedFile);

                ZipEntry entry = new ZipEntry(unzippedFile);
                zos.putNextEntry(entry);

                if ((unzippedFile.substring(unzippedFile.length()-1)).equals(File.separator))
                    continue;
                try{
                    fis = new FileInputStream(sourceFolder + unzippedFile);
                    int len=0;
                    while ((len = fis.read(buffer))>0) {
                        zos.write(buffer,0,len);
                    }
                } catch(IOException e) {
                    return false;
                } finally {
                    if (fis != null)
                        fis.close();
                }
            }
            zos.closeEntry();
        } catch(IOException e) {
            return false;
        } finally {
            zos.close();
            fileList = null;
            sourceFolder = null;
        }
        return true;
    }

    private void generateFileAndFolderList(File node) {
        if (node.isFile()) {
            fileList.add(generateZipEntry(node.getAbsoluteFile().toString()));
        }
        if (node.isDirectory()) {
            String dir = node.getAbsoluteFile().toString();
            fileList.add(dir.substring(sourceFolder.length(), dir.length()) + File.separator);

            String[] subNode = node.list();
            for (String fileOrFolderName : subNode) {
                generateFileAndFolderList(new File(node, fileOrFolderName));
            }
        }
    }

    private void updateSourceFolder(File node) {
        if (node.isFile() || node.isDirectory()) {
            String sf = node.getAbsoluteFile().toString();
            sourceFolder = sf.substring(0, (sf.lastIndexOf("/") > 0 ? sf.lastIndexOf("/") : sf.lastIndexOf("\\")));
            sourceFolder += File.separator;
        } else
            sourceFolder = null;
    }

    private String generateZipEntry(String file) {
        return file.substring(sourceFolder.length(), file.length());
    }
1
user3336194

Bei dieser Methode wird ein Ordner gezippt, und alle untergeordneten Dateien und Ordner (einschließlich leerer Ordner) werden der Zip-Datei hinzugefügt.

void zipFolder(Path sourceDir, Path targetFile) throws IOException {
    ZipDirectoryVisitor zipVisitor = new ZipDirectoryVisitor(sourceDir);
    Files.walkFileTree(sourceDir, zipVisitor);
    FileOutputStream fos = new FileOutputStream(targetFile.toString());
    ZipOutputStream zos = new ZipOutputStream(fos);
    byte[] buffer = new byte[1024];
    for (ZipEntry entry : zipVisitor.getZipEntries()) {
        zos.putNextEntry(entry);
        Path curFile = Paths.get(sourceDir.getParent().toString(), entry.toString());
        if (!curFile.toFile().isDirectory()) {
            FileInputStream in = new FileInputStream(Paths.get(sourceDir.getParent().toString(), entry.toString()).toString());
            int len;
            while ((len = in.read(buffer)) > 0) {
                zos.write(buffer, 0, len);
            }
            in.close();
        }
        zos.closeEntry();
    }
    zos.close();

}

Und hier ist die Implementierung von ZipDirectoryVisitor:

class ZipDirectoryVisitor extends SimpleFileVisitor<Path> {
    private Path dirToZip;
    private List<ZipEntry> zipEntries; // files and folders inside source folder as Zip entries
    public ZipDirectoryVisitor(Path dirToZip) throws IOException {
        this.dirToZip = dirToZip;
        zipEntries = new ArrayList<>();
    }

    @Override
    public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
        // According to Zip standard backslashes
        // should not be used in Zip entries
        String zipFile = dirToZip.getParent().relativize(path).toString().replace("\\", "/");
        ZipEntry entry = new ZipEntry(zipFile);
        zipEntries.add(entry);
        return FileVisitResult.CONTINUE;
    }


    @Override
    public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes basicFileAttributes) throws IOException {
        String zipDir = dirToZip.getParent().relativize(path).toString().replace("\\", "/");
        // Zip directory entries should end with a forward slash
        ZipEntry entry = new ZipEntry(zipDir + "/");
        zipEntries.add(entry);
        return FileVisitResult.CONTINUE;
    }


    @Override
    public FileVisitResult visitFileFailed(Path path, IOException e) throws IOException {
        System.err.format("Could not visit file %s while creating a file list from file tree", path);
        return FileVisitResult.TERMINATE;
    }

    public List<ZipEntry> getZipEntries() {
        return zipEntries;
    }
}