Рубрики
Без рубрики

Как создать Zip-файл на Java

В Java мы можем использовать `java.util.zip ` и `Файлы.копировать” для архивирования одного файла или целого каталога.

Автор оригинала: mkyong.

В этой статье показано несколько примеров архивирования одного файла и целого каталога (включая вложенные файлы и подкаталоги).

  1. Архивировать файл – java.util.zip
  2. Архивировать файл – Файлы.копировать в Файловые системы Zip
  3. Архивировать файл по требованию (без записи на диск)
  4. Заархивируйте дерево папок – файлов и java.util.zip
  5. Архивируйте дерево папок – файлов и Файлы.скопируйте в Файловые системы Zip
  6. zipj4 библиотека

В Java 7 представлен поставщик файловой системы Zip , объединенный с Files.copy , мы можем легко скопировать атрибуты файла в zip-файл (см. пример 4).

1. Заархивируйте один файл – java.util.zip

1.1 В этом примере Java используется java.util.zip . ZipOutputStream для архивирования одного файла.

package com.mkyong.io.howto;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFileExample1 {

    public static void main(String[] args) {

        Path source = Paths.get("/home/mkyong/test/Test.java");
        String zipFileName = "example.zip";

        try {

            ZipExample.zipSingleFile(source, zipFileName);

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Done");

    }

    // Zip a single file
    public static void zipSingleFile(Path source, String zipFileName)
        throws IOException {

        if (!Files.isRegularFile(source)) {
            System.err.println("Please provide a file.");
            return;
        }

        try (
            ZipOutputStream zos = new ZipOutputStream(
                new FileOutputStream(zipFileName));
            FileInputStream fis = new FileInputStream(source.toFile());
        ) {

            ZipEntry zipEntry = new ZipEntry(source.getFileName().toString());
            zos.putNextEntry(zipEntry);

            byte[] buffer = new byte[1024];
            int len;
            while ((len = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, len);
            }
            zos.closeEntry();
        }

    }
}

Выход

$ unzip -l example.zip
Archive:  example.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       32  2020-08-06 16:19   Test.java
---------                     -------
       32                     1 file

$ unzip example.zip
Archive:  example.zip
  inflating: Test.java               

2. Архивировать один файл – Файловые системы

2.1 В этом примере используется Java 7 NIO Файловые системы.newfilesystem для создания zip-файла и Files.copy для копирования файлов в zip-путь.

package com.mkyong.io.howto;

import java.io.*;
import java.net.URI;
import java.nio.file.*;
import java.util.HashMap;
import java.util.Map;

public class ZipFileExample2 {

    public static void main(String[] args) {

        Path source = Paths.get("/home/mkyong/test/Test.java");
        String zipFileName = "example.zip";

        try {

            ZipExample.zipSingleFileNio(source, zipFileName);

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Done");

    }

    // Zip a single file
    public static void zipSingleFileNio(Path source, String zipFileName)
        throws IOException {

        if (!Files.isRegularFile(source)) {
            System.err.println("Please provide a file.");
            return;
        }

        Map env = new HashMap<>();
        // Create the zip file if it doesn't exist
        env.put("create", "true");

        URI uri = URI.create("jar:file:/home/mkyong/" + zipFileName);

        try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {
            Path pathInZipfile = zipfs.getPath(source.getFileName().toString());

            // Copy a file into the zip file path
            Files.copy(source, pathInZipfile, StandardCopyOption.REPLACE_EXISTING);
        }

    }


}

3. Архивируйте один файл по требованию

В этом примере используется ByteArrayInputStream для прямого создания некоторых байтов по требованию и сохранения их в zip-файле без сохранения или записи данных в локальную файловую систему.

    // create a file on demand (without save locally) and add to zip
    public static void zipFileWithoutSaveLocal(String zipFileName) throws IOException {

        String data = "Test data \n123\n456";
        String fileNameInZip = "abc.txt";

        try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFileName))) {

            ZipEntry zipEntry = new ZipEntry(fileNameInZip);
            zos.putNextEntry(zipEntry);

            ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes());
            // one line, able to handle large size?
            //zos.write(bais.readAllBytes());

            // play safe
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bais.read(buffer)) > 0) {
                zos.write(buffer, 0, len);
            }

            zos.closeEntry();
        }

    }

Выход

$ unzip -l example.zip

Archive:  example.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       18  2020-08-11 18:44   abc.txt
---------                     -------
       18                     1 file

4. Заархивируйте папку или каталог – java.util.zip

4.1 Просмотрите каталог, содержащий некоторые вложенные файлы и подкаталоги.

$ tree /home/mkyong/test
test
â"œâ"€â"€ data
â"'   â""â"€â"€ db.debug.conf
â"œâ"€â"€ README.md
â"œâ"€â"€ test-a1.log
â"œâ"€â"€ test-a2.log
â"œâ"€â"€ test-b
â"'   â"œâ"€â"€ test-b1.txt
â"'   â"œâ"€â"€ test-b2.txt
â"'   â"œâ"€â"€ test-c
â"'   â"'   â"œâ"€â"€ test-c1.log
â"'   â"'   â""â"€â"€ test-c2.log
â"'   â""â"€â"€ test-d
â"'       â"œâ"€â"€ test-d1.log
â"'       â""â"€â"€ test-d2.log
â""â"€â"€ Test.java

4.2 В этом примере Java используется FileVisitor для обхода дерева файлов и ZipOutputStream для архивирования всего вручную, включая вложенные файлы и подкаталоги, но игнорируйте символические ссылки и атрибуты файлов.

package com.mkyong.io.howto;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipDirectoryExample {

    public static void main(String[] args) {

        Path source = Paths.get("/home/mkyong/test/");

        if (!Files.isDirectory(source)) {
            System.out.println("Please provide a folder.");
            return;
        }

        try {

            ZipDirectoryExample.zipFolder(source);

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Done");

    }

    // zip a directory, including sub files and sub directories
    public static void zipFolder(Path source) throws IOException {

        // get folder name as zip file name
        String zipFileName = source.getFileName().toString() + ".zip";

        try (
                ZipOutputStream zos = new ZipOutputStream(
                        new FileOutputStream(zipFileName))
        ) {

            Files.walkFileTree(source, new SimpleFileVisitor<>() {
                @Override
                public FileVisitResult visitFile(Path file,
                    BasicFileAttributes attributes) {

                    // only copy files, no symbolic links
                    if (attributes.isSymbolicLink()) {
                        return FileVisitResult.CONTINUE;
                    }

                    try (FileInputStream fis = new FileInputStream(file.toFile())) {

                        Path targetFile = source.relativize(file);
                        zos.putNextEntry(new ZipEntry(targetFile.toString()));

                        byte[] buffer = new byte[1024];
                        int len;
                        while ((len = fis.read(buffer)) > 0) {
                            zos.write(buffer, 0, len);
                        }

                        // if large file, throws out of memory
                        //byte[] bytes = Files.readAllBytes(file);
                        //zos.write(bytes, 0, bytes.length);

                        zos.closeEntry();

                        System.out.printf("Zip file : %s%n", file);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return FileVisitResult.CONTINUE;
                }

                @Override
                public FileVisitResult visitFileFailed(Path file, IOException exc) {
                    System.err.printf("Unable to zip : %s%n%s%n", file, exc);
                    return FileVisitResult.CONTINUE;
                }
            });

        }

    }

}

Выход

Zip file : /home/mkyong/test/test-a2.log
Zip file : /home/mkyong/test/test-a1.log
Zip file : /home/mkyong/test/data/db.debug.conf
Zip file : /home/mkyong/test/README.md
Zip file : /home/mkyong/test/Test.java
Zip file : /home/mkyong/test/test-b/test-b1.txt
Zip file : /home/mkyong/test/test-b/test-c/test-c2.log
Zip file : /home/mkyong/test/test-b/test-c/test-c1.log
Zip file : /home/mkyong/test/test-b/test-b2.txt
Zip file : /home/mkyong/test/test-b/test-d/test-d2.log
Zip file : /home/mkyong/test/test-b/test-d/test-d1.log

Done

Приведенный выше пример создает zip-файл в текущем рабочем каталоге, и мы не копировали атрибуты файла (просмотрите дату и время создания файла).

$ unzip -l test.zip

Archive:  test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2020-08-06 18:49   test-a2.log
        0  2020-08-06 18:49   test-a1.log
       14  2020-08-06 18:49   data/db.debug.conf
       42  2020-08-06 18:49   README.md
       32  2020-08-06 18:49   Test.java
        0  2020-08-06 18:49   test-b/test-b1.txt
        0  2020-08-06 18:49   test-b/test-c/test-c2.log
        0  2020-08-06 18:49   test-b/test-c/test-c1.log
        0  2020-08-06 18:49   test-b/test-b2.txt
        0  2020-08-06 18:49   test-b/test-d/test-d2.log
        0  2020-08-06 18:49   test-b/test-d/test-d1.log
---------                     -------
       88                     11 files

5. Архивировать папку или каталог – Файловые системы

5.1 В этом примере используется тот же FileVisitor для обхода дерева файлов. Тем не менее, на этот раз мы используем Файловые системы URL для создания zip-файла и Files.copy для копирования файлов в zip-путь, включая атрибуты файла , но игнорируем символическую ссылку.

package com.mkyong.io.howto;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;

public class ZipDirectoryExample {

    public static void main(String[] args) {

        Path source = Paths.get("/home/mkyong/test/");

        if (!Files.isDirectory(source)) {
            System.out.println("Please provide a folder.");
            return;
        }

        try {

            ZipDirectoryExample.zipFolderNio(source);

        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println("Done");

    }

    public static void zipFolderNio(Path source) throws IOException {

        // get current working directory
        String currentPath = System.getProperty("user.dir") + File.separator;

        // get folder name as zip file name
        // can be other extension, .foo .bar .whatever
        String zipFileName = source.getFileName().toString() + ".zip";
        URI uri = URI.create("jar:file:" + currentPath + zipFileName);

        Files.walkFileTree(source, new SimpleFileVisitor<>() {
            @Override
            public FileVisitResult visitFile(Path file,
                BasicFileAttributes attributes) {

                // Copying of symbolic links not supported
                if (attributes.isSymbolicLink()) {
                    return FileVisitResult.CONTINUE;
                }

                Map env = new HashMap<>();
                env.put("create", "true");

                try (FileSystem zipfs = FileSystems.newFileSystem(uri, env)) {

                    Path targetFile = source.relativize(file);
                    Path pathInZipfile = zipfs.getPath(targetFile.toString());

                    // NoSuchFileException, need create parent directories in zip path
                    if (pathInZipfile.getParent() != null) {
                        Files.createDirectories(pathInZipfile.getParent());
                    }

                    // copy file attributes
                    CopyOption[] options = {
                            StandardCopyOption.REPLACE_EXISTING,
                            StandardCopyOption.COPY_ATTRIBUTES,
                            LinkOption.NOFOLLOW_LINKS
                    };
                    // Copy a file into the zip file path
                    Files.copy(file, pathInZipfile, options);

                } catch (IOException e) {
                    e.printStackTrace();
                }

                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) {
                System.err.printf("Unable to zip : %s%n%s%n", file, exc);
                return FileVisitResult.CONTINUE;
            }

        });

    }

}

Выход

$ unzip -l test.zip
Archive:  test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2020-07-27 15:10   test-a2.log
        0  2020-07-23 14:55   test-a1.log
        0  2020-08-06 18:57   data/
       14  2020-08-04 14:07   data/db.debug.conf
       42  2020-08-05 19:04   README.md
       32  2020-08-05 19:04   Test.java
        0  2020-08-06 18:57   test-b/
        0  2020-07-24 15:49   test-b/test-b1.txt
        0  2020-08-06 18:57   test-b/test-c/
        0  2020-07-27 15:11   test-b/test-c/test-c2.log
        0  2020-07-27 15:11   test-b/test-c/test-c1.log
        0  2020-07-27 15:10   test-b/test-b2.txt
        0  2020-08-06 18:57   test-b/test-d/
        0  2020-07-27 15:11   test-b/test-d/test-d2.log
        0  2020-07-27 15:11   test-b/test-d/test-d1.log
---------                     -------
       88                     15 files

# unzip to an external folder abc
$ unzip test.zip -d abc

Archive:  test.zip
 inflating: abc/test-a2.log         
 inflating: abc/test-a1.log         
  creating: abc/data/
 inflating: abc/data/db.debug.conf  
 inflating: abc/README.md           
 inflating: abc/Test.java           
  creating: abc/test-b/
 inflating: abc/test-b/test-b1.txt  
  creating: abc/test-b/test-c/
 inflating: abc/test-b/test-c/test-c2.log  
 inflating: abc/test-b/test-c/test-c1.log  
 inflating: abc/test-b/test-b2.txt  
  creating: abc/test-b/test-d/
 inflating: abc/test-b/test-d/test-d2.log  
 inflating: abc/test-b/test-d/test-d1.log  

$ tree abc
abc
â"œâ"€â"€ data
â"'   â""â"€â"€ db.debug.conf
â"œâ"€â"€ README.md
â"œâ"€â"€ test-a1.log
â"œâ"€â"€ test-a2.log
â"œâ"€â"€ test-b
â"'   â"œâ"€â"€ test-b1.txt
â"'   â"œâ"€â"€ test-b2.txt
â"'   â"œâ"€â"€ test-c
â"'   â"'   â"œâ"€â"€ test-c1.log
â"'   â"'   â""â"€â"€ test-c2.log
â"'   â""â"€â"€ test-d
â"'       â"œâ"€â"€ test-d1.log
â"'       â""â"€â"€ test-d2.log
â""â"€â"€ Test.java

6. Zip-файл – zip4j

zip4j – популярная zip-библиотека на Java; она имеет множество дополнительных функций, таких как защищенный паролем zip-файл, разделенный zip-файл, шифрование AES и т. Д. Пожалуйста, посетите zip4j github для получения дополнительной документации и использования.

Вот некоторые распространенные способы архивирования файлов и папок.

import net.lingala.zip4j.ZipFile;

//...
  public static void zip4j() throws IOException {

      // zip file with a single file
      new ZipFile("filename.zip").addFile("file.txt");

      // zip file with multiple files
      List files = Arrays.asList(
              new File("file1.txt"), new File("file2.txt"));
      new ZipFile("filename.zip").addFiles(files);

      // zip file with a folder
      new ZipFile("filename.zip").addFolder(new File("/home/mkyong/folder"));


  }

Дальнейшее чтение Как распаковать zip-файл на Java

Скачать Исходный Код

$ клон git $ клон git

$ cd java-ввод-вывод

Рекомендации

Оригинал: “https://mkyong.com/java/how-to-compress-files-in-zip-format/”