Интерфейс сжатия данных в формате GZIP является наиболее простым и идеально подходит для ситуаций, где имеется один поток данных, который необходимо уплотнить (а не разрозненные фрагменты данных). В следующем примере сжимается файл:
// io/GZIPcompress java // {Параметры- GZIPcompress.java} import java util zip *, import java io *.
public class GZIPcompress {
public static void main(String[] args)
throws IOException {
if(args.length == 0) {
System out.printlnC
"Использование: \nGZIPcompress file\n" + "иИспользует метод GZIP для сжатия " + "файла в архив test.gz"); System.exit(l),
}
BufferedReader in = new BufferedReader( new FileReader(args[0])),
BufferedOutputStream out = new BufferedOutputStrearrK new GZIPOutputStreamC
new FileOutputStreamC'test gz"))),
System.out.println("3anncb файла");
int с;
while((c = in.readO) != -1) out.write(c);
in.closeO;
out.closeO;
System.out.printlnC"Чтение файла");
BufferedReader in2 = new BufferedReader(
new InputStreamReader(new GZIPInputStreamC new FilelnputStreamC'test gz")))).
String s;
while((s = in2 readLineO) != null) System.out.printin(s);
}
} ///:-
Работать с классами сжатия данных очень просто: вы просто надстраиваете их для своего потока данных (GZIPOutputStream или ZipOutputStream для сжатия, GZIPInputStream или ZipInputStream для распаковки данных). Дальнейшее сводится к элементарным операциям ввода/вывода. В примере продемонстрированы смешанные байтовые и символьные потоки: поток in основан на Reader, тогда как конструктор класса GZIPOutputStream использует только потоки на основе OutputStream, но не Writer. Поэтому при открытии файла поток GZIPInputStream преобразуется в символьный поток Reader.
Многофайловые архивы ZIP
Библиотека, поддерживающая формат сжатия данных ZIP, обладает гораздо более широкими возможностями. С ее помощью можно легко упаковывать произвольное количество файлов, а для чтения файлов в формате ZIP даже определен отдельный класс. В библиотеке поддержан стандартный ZIP-формат, поэтому сжатые ею данные будут восприниматься практически любым упаковщиком. Структура следующего примера совпадает со структурой предыдущего, но количество файлов, указываемых в командной строке, не ограничено. Вдобавок демонстрируется применение класса Checksum для получения и проверки контрольной суммы. Таких типов контрольных сумм в Java два: один представлен классом АсИег32'(этот алгоритм быстрее), а другой — классом CRC32 (медленнее, но точнее).
//: io/ZipCompress.java
// Использование формата ZIP для сжатия любого
// количества файлов, указанных в командной строке.
// {Параметры. ZipCompress java}
import java.util zip *;
import java io *;
import java.util *,
import static net mindview.util Print *,
public class ZipCompress {
public static void mainCString[] args) throws IOException {
FileOutputStream f = new FileOutputStreamC'test zip"). CheckedOutputStream csum =
new CheckedOutputStream(f. new Adler320). ZipOutputStream zos = new ZipOutputStream(csum). BufferedOutputStream out =
new BufferedOutputStream(zos). zos setComment("Проверка ZIP-сжатия Java"). // Однако парного метода для получения комментария // getCommentO не существует for(String arg . args) {
print("3anncb файла " + arg). BufferedReader in =
new BufferedReader(new FileReader(arg)); zos putNextEntry(new ZipEntry(arg)). int c.
while((c = in readO) != -1)
out write(c); in closeO. out flushO.
}
out closeO.
// Контрольная сумма становится действительной
// только после закрытия файла с архивом!
pri nt ("Checksum " + csum getChecksum() getValueO);
// Теперь извлекаем файлы-
ргШСЧтение файла").
Fi 1 elnputStream fi = new FilelnputStreamCtest zip"). CheckedlnputStream csumi =
new CheckedInputStream(fi. new Adler320); ZipInputStream in2 = new ZipInputStream(csumi). BufferedlnputStream bis = new BufferedInputStream(in2). ZipEntry ze.
while((ze = in2 getNextEntry()) != null) { printCReading file " + ze). int x;
while((x = bis readO) != -1) System out write(x).
}
if(args.length == 1)
print("Контрольная сумма " + csumi getChecksum() getValueO), bis closeO.
// Альтернативный способ открытия и чтения
// файлов в формате ZIP•
ZipFile zf = new ZipFi1e("test zip").
Enumeration e = zf entriesO;
while(e hasMoreElementsO) {
ZipEntry ze2 = (ZipEntry)e nextElement().
printCFile. " + ze2).
// ... затем данные извлекаются так же. как прежде
}
/* if(args length == 1) */
}
} ///:-