Архивирование и разархивирование в Java

1. Обзор

В этом кратком руководстве мы обсудим, как заархивировать файл в архив и как распаковать архив — все с использованием ядра библиотеки, предоставляемые Java.

Эти базовые библиотеки являются частью пакета — где мы можем найти все утилиты, связанные с архивированием и распаковкой.

2. Архивирование файла

Давайте сначала рассмотрим простую операцию — архивирование одного файла.

Для В нашем примере мы заархивируем файл с именем test1.txt в архив с именем compressed.zip .

Конечно, сначала мы получим доступ к файлу с диска — давайте посмотрим:

  public class ZipFile {public static void  main (String [] args) выбрасывает исключение IOException {String sourceFile = "test1.txt";  FileOutputStream fos = новый FileOutputStream ("compressed.zip");  ZipOutputStream zipOut = новый ZipOutputStream (fos);  Файл fileToZip = новый файл (исходный файл);  FileInputStream fis = новый FileInputStream (fileToZip);  ZipEntry zipEntry = новый ZipEntry (fileToZip.getName ());  zipOut.putNextEntry (zipEntry);  byte [] bytes = новый байт [1024];  int length;  while ((длина = fis.read (байты))> = 0) {zipOut.write (байты, 0, длина);  } zipOut.close ();  fis.close ();  fos.close ();  }}  

3. Заархивировать несколько файлов

Теперь давайте посмотрим, как заархивировать несколько файлов в один zip-файл. Мы сжимаем test1.txt и test2.txt в multiCompressed.zip :

  открытый класс ZipMultipleFiles {public static void main (String [] args) выдает исключение IOException {List  srcFiles = Arrays.asList ("test1.txt", "test2.txt");  FileOutputStream fos = новый FileOutputStream ("multiCompressed.zip");  ZipOutputStream zipOut = новый ZipOutputStream (fos);  for (String srcFile: srcFiles) {File fileToZip = новый файл (srcFile);  FileInputStream fis = новый FileInputStream (fileToZip);  ZipEntry zipEntry = новый ZipEntry (fileToZip.getName ());  zipOut.putNextEntry (zipEntry);  byte [] bytes = новый байт [1024];  int length;  а ((длина = fis.read (байты))> = 0) {zipOut.write (байты, 0, длина);  } fis.close ();  } zipOut.close ();  fos.close ();  }}  

4. Заархивируйте каталог

Теперь давайте обсудим, как заархивировать весь каталог. Мы каталогизируем zipTest в dirCompressed.zip :

  public class ZipDirectory {public static void main (  String [] args) выбрасывает исключение IOException {String sourceFile = "zipTest";  FileOutputStream fos = новый FileOutputStream ("dirCompressed.zip");  ZipOutputStream zipOut = новый ZipOutputStream (fos);  Файл fileToZip = новый файл (исходный файл);  zipFile (fileToZip, fileToZip.getName (), zipOut);  zipOut.close ();  фос. Закрыть();  } private static void zipFile (File fileToZip, String fileName, ZipOutputStream zipOut) выдает исключение IOException {if (fileToZip.isHidden ()) {return;  } if (fileToZip.isDirectory ()) {if (fileName.endsWith ("/")) {zipOut.putNextEntry (новый ZipEntry (имя_файла));  zipOut.closeEntry ();  } else {zipOut.putNextEntry (новый ZipEntry (fileName + "/"));  zipOut.closeEntry ();  } Файл [] children = fileToZip.listFiles ();  для (Файл childFile: children) {zipFile (childFile, fileName + "/" + childFile.getName (), zipOut);  } возвращение;  } FileInputStream fis = новый FileInputStream (fileToZip);  ZipEntry zipEntry = новый ZipEntry (имя_файла);  zipOut.putNextEntry (zipEntry);  byte [] bytes = новый байт [1024];  int length;  while ((длина = fis.read (байты))> = 0) {zipOut.write (байты, 0, длина);  } fis.close ();  }}  

Обратите внимание, что:

  • Чтобы заархивировать подкаталоги, мы перебираем их рекурсивно.
  • Каждый раз, когда мы находим каталог, мы добавляем его имя к имени потомков ZipEntry , чтобы сохранить иерархию.
  • Мы также создаем запись каталога для каждого пустой каталог

5. Разархивируйте архив

Давайте теперь распакуем архив и извлечем его содержимое.

В этом примере мы ‘ Разархивирую compressed.zip в новую папку с именем unzipTest .

Давайте посмотрим:

  открытый класс UnzipFile {public static void main (String [] args) выдает исключение IOException {String fileZip = "src/main/resources/unzipTest/compressed.zip"  ;  Файл destDir = новый файл ("src/main/resources/unzipTest");  байт [] буфер = новый байт [1024];  ZipInputStream zis = новый ZipInputStream (новый FileInputStream (fileZip));  ZipEntry zipEntry = zis.getNextEntry ();  while (zipEntry! = null) {//...} zis.closeEntry ();  zis.close ();  }}  

Внутри цикла while мы перебираем каждый ZipEntry и сначала проверьте, является ли это каталогом . Если это так, то мы создадим каталог с помощью метода mkdirs () ; в противном случае мы продолжим создание файла:

  while (zipEntry! = null) {File newFile = newFile (destDir, zipEntry);  if (zipEntry.isDirectory ()) {if (! newFile.isDirectory () &&! newFile.mkdirs ()) {выбросить новое исключение IOException («Не удалось создать каталог» + newFile);  }} else {//исправление для архивов, созданных Windows File parent = newFile.getParentFile ();  if (! parent.isDirectory () &&! parent.mkdirs ()) {выбросить новое исключение IOException ("Не удалось создать каталог" + родительский);  }//записываем содержимое файла FileOutputStream fos = new FileOutputStream (newFile);  int len;  в то время как ((len = zis.read (буфер))> 0) {fos.write (буфер, 0, len);  } fos.close ();  } zipEntry = zis.getNextEntry ();}  

Следует отметить, что в ветке else мы также сначала проверяем, родительский каталог файла существует. Это необходимо для архивов, созданных в Windows, где корневые каталоги не имеют соответствующей записи в zip-файле.

Еще один ключевой момент можно увидеть в newFile () метод:

  общедоступный статический файл newFile (File destinationDir, ZipEntry zipEntry) выдает исключение IOException {File destFile = new File (destinationDir, zipEntry.getName ());  Строка destDirPath = destinationDir.getCanonicalPath ();  Строка destFilePath = destFile.getCanonicalPath ();  if (! destFilePath.startsWith (destDirPath + File.separator)) {выбросить новое исключение IOException ("Запись находится за пределами целевого каталога:" + zipEntry.getName ());  } return destFile;}  

Этот метод защищает от записи файлов в файловую систему за пределами целевой папки. Эта уязвимость называется Zip Slip, и вы можете прочитать о ней здесь.

6. Заключение

В этом руководстве показано, как мы можем использовать библиотеки Java для операций сжатия и распаковки файлов.

Реализацию этих примеров можно найти на GitHub.

Java bottom

Я просто объявила о новом курсе Learn Spring , посвященном основам Spring 5 и Spring Boot 2:

>> ПРОВЕРИТЬ КУРС



Добавление 2 файлов в zip-архив с помощью Java

I нужно поместить 2 файла в один zip архив, используя java. Я использую следующий код, и он отлично работает с одним файлом. Когда я вызываю метод с двумя файлами, он не генерирует никаких исключений, но в результате я сломал файл

  private File createZipFile (File [] files) выдает IOException {File  zipFile = новый файл ("D: \ zip.zip");  FileOutputStream fileOutputStream = новый FileOutputStream (zipFile);  ZipOutputStream zipOutputStream = новый ZipOutputStream (новый BufferedOutputStream (fileOutputStream));  для (Файл файл: файлы) {BufferedInputStream bufferedInputStream = null;  байтовые данные [] = новый байт [1024];  FileInputStream fileInputStream = новый FileInputStream (file.getAbsolutePath ());  bufferedInputStream = новый BufferedInputStream (fileInputStream, 1024);  Запись ZipEntry = новый ZipEntry (file.getName ());  zipOutputStream.putNextEntry (запись);  int count;  в то время как ((счетчик = bufferedInputStream.read (данные, 0, 1024))! = -1) {zipOutputStream.write (данные, 0, счетчик);  } bufferedInputStream.close ();  fileInputStream.close ();  } zipOutputStream.close ();  return zipFile;  }  

Похоже, вам не хватает zipOutputStream.closeEntry () в конце цикла.

Оцените статью
logicle.ru
Добавить комментарий