Кроме общего функционала для работы с файлами Java предоставляет функциональность для работы с таким видом файлов как zip-архивы. Для этого в пакете java.util.zip определены два класса - ZipInputStream и ZipOutputStream
Для создания архива используется класс ZipOutputStream. Для создания объекта ZipOutputStream в его конструктор передается поток вывода:
ZipOutputStream(OutputStream out)
Для записи файлов в архив для каждого файла создается объект ZipEntry
, в конструктор которого передается имя архивируемого файла. А чтобы
добавить каждый объект ZipEntry в архив, применяется метод putNextEntry().
Создадим архив:
import java.io.*; import java.util.zip.*; public class Program { public static void main(String[] args) { String filename = "notes.txt"; try(ZipOutputStream zout = new ZipOutputStream(new FileOutputStream("output.zip")); FileInputStream fis= new FileInputStream(filename);) { ZipEntry entry1=new ZipEntry("notes.txt"); zout.putNextEntry(entry1); // считываем содержимое файла в массив byte byte[] buffer = new byte[fis.available()]; fis.read(buffer); // добавляем содержимое к архиву zout.write(buffer); // закрываем текущую запись для новой записи zout.closeEntry(); } catch(Exception ex){ System.out.println(ex.getMessage()); } } }
После добавления объекта ZipEntry в поток нам также надо добавить в него и содержимое файла. Для этого используется метод write, записывающий в поток
массив байтов: zout.write(buffer);
. В конце надо закрыть ZipEntry с помощью метода closeEntry()
. После этого можно добавлять в архив
новые файлы - в этом случае все вышеописанные действия для каждого нового файла повторяются.
Для чтения архивов применяется класс ZipInputStream
. В конструкторе он принимает поток, указывающий на zip-архив:
ZipInputStream(InputStream in)
Для считывания файлов из архива ZipInputStream использует метод getNextEntry(), который возвращает объект ZipEntry. Объект ZipEntry представляет отдельную запись в zip-архиве. Например, считаем какой-нибудь архив:
import java.io.*; import java.util.zip.*; public class Program { public static void main(String[] args) { try(ZipInputStream zin = new ZipInputStream(new FileInputStream("output.zip"))) { ZipEntry entry; String name; while((entry=zin.getNextEntry())!=null){ name = entry.getName(); // получим название файла System.out.printf("File name: %s \n", name); // распаковка FileOutputStream fout = new FileOutputStream("new" + name); for (int c = zin.read(); c != -1; c = zin.read()) { fout.write(c); } fout.flush(); zin.closeEntry(); fout.close(); } } catch(Exception ex){ System.out.println(ex.getMessage()); } } }
ZipInputStream в конструкторе получает ссылку на поток ввода. И затем в цикле выводятся все файлы и их размер в байтах, которые находятся в данном архиве.
Затем данные извлекаются из архива и сохраняются в новые файлы, которые находятся в той же папке и которые начинаются с "new".