Кроме общего функционала для работы с файлами 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".