Автор оригинала: mkyong.
В этой статье показано несколько примеров архивирования одного файла и целого каталога (включая вложенные файлы и подкаталоги).
- Архивировать файл –
java.util.zip
- Архивировать файл –
Файлы.копировать
вФайловые системы Zip
- Архивировать файл по требованию (без записи на диск)
- Заархивируйте дерево папок – файлов и
java.util.zip
- Архивируйте дерево папок – файлов и
Файлы.скопируйте
вФайловые системы Zip
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; } Mapenv = 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; } Mapenv = 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 Listfiles = 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-ввод-вывод
Рекомендации
- Поставщик Файловой системы Zip
- Спецификация формата ZIP-файла
- Файловый редактор JavaDoc
- Как получить текущий рабочий каталог на Java
- ZipOutputStream JavaDoc
- zip4j github
- Как распаковать zip-файл на Java
Оригинал: “https://mkyong.com/java/how-to-compress-files-in-zip-format/”