Чтение онлайн

ЖАНРЫ

Философия Java3

Эккель Брюс

Шрифт:

}

public void runО { try {

// Монопольная блокировка без перекрытия;

FileLock fl = fc.lock(start, end, false);

System.out.println("Заблокировано: "+ start +" to "+ end);

// Модификация:

while(buff.position < buff.limitO - 1) buff.put((byte)(buff.get О + 1)); fl.releasee);

System.out.println("Освобождено: "+start+" to "+ end); } catch(IOException e) {

throw new RuntimeException(e);

}

}

}

} ///:-

Класс потока LockAndModify устанавливает область буфера и получает его для модификации методом slice. В методе run для файлового канала устанавливается

блокировка (вы не вправе запросить блокировку для буфера, это позволено только для канала). Вызов lock напоминает механизм синхронизации доступа потоков к объектам, у вас появляется некая «критическая секция» с монопольным доступом к данной части файла.

Блокировки автоматически снимаются при завершении работы JVM, закрытии канала, для которого они были получены, но можно также явно вызвать метод releaseQ объекта FileLock, что здесь и показано.

Сжатие данных

Библиотека ввода/вывода Java содержит классы, поддерживающие ввод/вывод в сжатом формате (табл. 16.8). Они базируюся на уже существующих потоках ввода/вывода.

Эти классы не являются частью иерархии символьно-ориентированных потоков Reader и Writer, они надстроены над байт-ориентированными классами InputStream и OutputStream, так как библиотека сжатия работает не с символами, а с байтами. Впрочем, никто не запрещает смешивать потоки. (Помните, как легко преобразовать потоки из байтовых в символьные — достаточно использовать классы InputStreamReader и OutputStreamWriter.)

Таблица 16.8. Классы для сжатия данных

Назначение

CheckedlnputStream

CheckedOutputStream

DeflaterOutputStream ZipOutputStream

GZIPOutputStream

InflaterlnputStream ZipInputStream

GZIPInputStream

Название класса

Его метод getCheckSum возвращает контрольную сумму для любого входного потока InputStream (не только для потока распаковки) Его метод getCheckSum возвращает контрольную сумму для любого выходного потока OutputStream (не только для потока сжатия) Базовый класс для классов сжатия данных

Подкласс DeflaterOutputStream, который производит сжатие данных в формате файлов ZIP

Подкласс DeflaterOutputStream, который производит сжатие данных в формате файлов GZIP

Базовый класс для классов распаковки сжатых данных

Подкласс InflaterlnputStream, который распаковывает сжатые данные,

хранящиеся в формате файлов ZIP

Подкласс InflaterlnputStream, распаковывающий сжатые данные, хранящиеся в формате файлов GZIP

Хотя существует великое количество различных программ сжатия данных, форматы ZIP и GZIP используются, пожалуй, чаще всего. Таким образом, вы можете легко манипулировать своими сжатыми данными с помощью многочисленных программ, предназначенных для чтения и записи этих форматов.

Простое сжатие в формате GZIP

Интерфейс сжатия данных в формате 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.

Поделиться с друзьями: