Книга е още в много ранна фаза на написване



страница64/73
Дата25.07.2016
Размер13.53 Mb.
#6732
1   ...   60   61   62   63   64   65   66   67   ...   73

Компресия


Java 1.1 също е добавил класове за четене и писане на файлове в компресиран формат. Те обгръщат съществуващите IO за получаване на възможност за ком­преси­ране/декомпресиране на данните.

Един аспект на тези Java 1.1 класове изпъква: Те не са извлечени от Reader и Writer, а вместо това са част от InputStream и OutputStream йерархиите. Така мо­же да се наложи да смесите двата типа потоци. (Помнете че може да из­полз­ва­те InputStreamReader и OutputStreamWriter за лесно преминаване от еди­ния в другия и обратно.)



Java 1.1 Клас за компресия

Функция

CheckedInputStream

GetCheckSum( ) дава контролна сума за всеки InputStream (не само декомпресия)

CheckedOutputStream

GetCheckSum( ) дава контролна сума за всеки OutputStream (не само декомпресия)

DeflaterOutputStream

Базов за класовете за компресия

ZipOutputStream

DeflaterOutputStream който компресира във формата на Zip файл

GZIPOutputStream

DeflaterOutputStream който компресира във формата на GZIP файл

InflaterInputStream

Базов за класовете за декомпресия

ZipInputStream

DeflaterInputStream който декомпресира от Zip формат

GZIPInputStream

DeflaterInputStream който декомпресира от GZIP формат

Макар и да има много алгоритми за компресия, Zip и GZIP са вероятно най-из­полз­ваните. Така че лесно може да работите с компресираните си данни чрез мно­жеството налични инструменти.

Проста компресия с GZIP


GZIP интерфейсът е прост и затова може би по-подходящ когато имате едно пар­че данни за компресиране (в противоположност на множество различни пар­чета). Ето пример за компресиране на един файл:

//: c10:ZipCompress.java

// Uses Java 1.1 Zip compression to compress

// any number of files whose names are passed

// on the command line.

import java.io.*;

import java.util.*;

import java.util.zip.*;


public class ZipCompress {

public static void main(String[] args) {

try {

FileOutputStream f =



new FileOutputStream("test.zip");

CheckedOutputStream csum =

new CheckedOutputStream(

f, new Adler32());

ZipOutputStream out =

new ZipOutputStream(

new BufferedOutputStream(csum));

out.setComment("A test of Java Zipping");

// Can't read the above comment, though

for(int i = 0; i < args.length; i++) {

System.out.println(

"Writing file " + args[i]);

BufferedReader in =

new BufferedReader(

new FileReader(args[i]));

out.putNextEntry(new ZipEntry(args[i]));

int c;

while((c = in.read()) != -1)



out.write(c);

in.close();

}

out.close();



// Checksum valid only after the file

// has been closed!

System.out.println("Checksum: " +

csum.getChecksum().getValue());

// Now extract the files:

System.out.println("Reading file");

FileInputStream fi =

new FileInputStream("test.zip");

CheckedInputStream csumi =

new CheckedInputStream(

fi, new Adler32());

ZipInputStream in2 =

new ZipInputStream(

new BufferedInputStream(csumi));

ZipEntry ze;

System.out.println("Checksum: " +

csumi.getChecksum().getValue());

while((ze = in2.getNextEntry()) != null) {

System.out.println("Reading file " + ze);

int x;


while((x = in2.read()) != -1)

System.out.write(x);

}

in2.close();



// Alternative way to open and read

// zip files:

ZipFile zf = new ZipFile("test.zip");

Enumeration e = zf.entries();

while(e.hasMoreElements()) {

ZipEntry ze2 = (ZipEntry)e.nextElement();

System.out.println("File: " + ze2);

// ... and extract the data as before

}

} catch(Exception e) {



e.printStackTrace();

}

}



} ///:~

Използването на класовете е праволинейно – просто обгръщате изходния си по­ток с GZIPOutputStream или ZipOutputStream и входния си поток с GZIPInputStream или ZipInputStream. Всичко друго е обикновено IO четене и пи­сане. Това обаче е хубав пример за случай, когато сте принудени да смесвате старите и новите IO потоци: in използва Reader класове, докато конструктора на GZIPOutputStream може да приеме само OutputStream обект, не Writer обект.


Много файлове със Zip


Библиотеката на Java 1.1 която поддържа Zip формата е много по-богата. С нея може лесно да компресирате множество файлове, даже има отделен клас който пра­ви четенето на Zip файл лесно. Библиотеката използва стандартния Zip фор­мат така че несъмнено е съвместива с данните и инструментите които могат да се изтеглят от Мрежата. Следният пример има същата форма като предишния, но позволява колкото искате аргументи на командния ред. Освен това показва из­ползването на Checksum класовете за изчисление и проверка на контролна сума за файловете. Има два Checksum типа: Adler32 (който е по-бърз) и CRC32 (който е по-бавен но мъничко по-акуратен).

//: c10:ZipCompress.java

// Uses Java 1.1 Zip compression to compress

// any number of files whose names are passed

// on the command line.

import java.io.*;

import java.util.*;

import java.util.zip.*;


public class ZipCompress {

public static void main(String[] args) {

try {

FileOutputStream f =



new FileOutputStream("test.zip");

CheckedOutputStream csum =

new CheckedOutputStream(

f, new Adler32());

ZipOutputStream out =

new ZipOutputStream(

new BufferedOutputStream(csum));

out.setComment("A test of Java Zipping");

// Can't read the above comment, though

for(int i = 0; i < args.length; i++) {

System.out.println(

"Writing file " + args[i]);

BufferedReader in =

new BufferedReader(

new FileReader(args[i]));

out.putNextEntry(new ZipEntry(args[i]));

int c;

while((c = in.read()) != -1)



out.write(c);

in.close();

}

out.close();



// Checksum valid only after the file

// has been closed!

System.out.println("Checksum: " +

csum.getChecksum().getValue());

// Now extract the files:

System.out.println("Reading file");

FileInputStream fi =

new FileInputStream("test.zip");

CheckedInputStream csumi =

new CheckedInputStream(

fi, new Adler32());

ZipInputStream in2 =

new ZipInputStream(

new BufferedInputStream(csumi));

ZipEntry ze;

System.out.println("Checksum: " +

csumi.getChecksum().getValue());

while((ze = in2.getNextEntry()) != null) {

System.out.println("Reading file " + ze);

int x;


while((x = in2.read()) != -1)

System.out.write(x);

}

in2.close();



// Alternative way to open and read

// zip files:

ZipFile zf = new ZipFile("test.zip");

Enumeration e = zf.entries();

while(e.hasMoreElements()) {

ZipEntry ze2 = (ZipEntry)e.nextElement();

System.out.println("File: " + ze2);

// ... and extract the data as before

}

} catch(Exception e) {



e.printStackTrace();

}

}



} ///:~

За да добавите всеки файл към архива трябва да извикате putNextEntry( ) и да му дадете ZipEntry обект. ZipEntry съдържа богат интерфейс който позволява да добавите всичките данни налични в случая в Zip файла: име, дължини ком­пре­сиран и некомпресиран, дата, CRC сума, допълнителни данни, коментар, ме­тод на компресия и път ако има. Макар и Zip форматът да има начин за даване на парола, това не се поддържа в библиотеката на Java за Zip. И макар че CheckedInputStream и CheckedOutputStream поддържат и Adler32 и CRC32 кон­тролни суми, класът ZipEntry поддържа само интерфейс за CRC. Това е огра­ничение произтичащо от подлежащия Zip формат, но би могло да ви отклони от използването на по-бъързия Adler32.

За извличане на файлове ZipInputStream има getNextEntry( ) метод който връ­ща следващия ZipEntry ако има такъв. Като по-сбита алтернатива може да про­че­тете файла със ZipFile обект, който има метод entries( ) с връщане на Enumeration към ZipEntries-ите.

За да четете контролната сума трябва да имате някакъв достъп до асоциирания Checksum обект. Тук се запазват манипулатори към CheckedOutputStream и CheckedInputStream, но също би могъл да бъде и манипулатор на Checksum обект.

Объркващ метод в Zip потоците е setComment( ). Както е показано по-горе, може да се слага коментар когато се пише файл, но няма начин да се възстанови той в ZipInputStream. Коментарите изглежда се поддържат за всяка порция дан­ни чрез ZipEntry.

Разбира се не сте ограничени до файлове когато използвате GZIP или Zip би­блио­теките – може да компресирате каквите и да е данни, включително за из­пра­щане по Интернет.


Java archive (jar) утилитито


Zip форматът се използва също и в Java 1.1 JAR (Java ARchive) файловия формат, който е начин да се събере група файлове в един компресиран файл, точ­но както Zip. Само че както всичко в Java, JAR файловете са мно­го­плат­фор­ме­ни, така че не трябва да се безпокоите по въпросите за преносимост. Може да се включват и звукови файлове и образи, както и файлове с класове.

JAR файловете са в частност полезни когато имате работа с Internet. Преди JAR фай­ловете вашият Web браузър трябваше да прави множество поръчки към Web сървъра за да получи всичките файлове които съставят даден аплет. Освен то­ва всеки файл беше некомпресиран. Чрез комбинирането на всички необ­хо­ди­ми за аплета файлове в единствен JAR файл остава необходим само един достъп и освен това обменът е по-бърз поради компресията. И всяка единица в JAR файла може да бъде цифрово подписана за сигурност (вижте Java до­ку­мен­та­цията за подробности).

Един JAR файл се състои от множество зипнати фойлове задедно с “манифест” кой­то ги описва. (Може да създадете ваш собствен файл-манифест; иначе jar про­грамата ще го направи.) Може да намерите повече за JAR манифестите в он­лайн документацията.

jar утилитито което идва с JDK на Sun автоматично компрериса файлове по ваш избор. Вика се с команден ред:

jar [options] destination [manifest] inputfile(s)

Опциите са просто колекция от букви (не са необходими чертички или други подобни). Те са:


c

Създава нов или празен архив.

t

Дава съдържанието.

x

Изважда всички файлове

x file

Изважда споменатия файл

f

Казва: “Ще ви дам името на файла.” Ако не използвате това, jar предполага че ще чете от стандратния вход, или, ако създава файл, ще го праща на стандартния изход.

m

Казва че първият аргумент ще бъде името на потребителския манифестов файл

v

Създава изход описващ какво прави jar

O

Само запомня файловете; не ги компресира (използвайте го да създаде JAR файл който може да сложите във вашия път към класовете)

M

Не създава автоматично манифестен файл

Ако файловете които се вкарват в JAR файла включват поддиректория, тя се до­бавя автоматично, включително всичките поддиректории и т.н. Ин­фор­ма­ция­та за пътя също се запазва.

Ето някои типични начини за викане на jar:

jar cf myJarFile.jar *.class

Това създава JAR файл наречен myJarFile.jar който съдържа всичките класови файлове в текущата поддиректория, заедно с автоматично генериран мани­фе­стен файл.

jar cmf myJarFile.jar myManifestFile.mf *.class

Като предишния пример, но с добавяне на създаден от потребителя манифест на­речен myManifestFile.mf.

jar tf myJarFile.jar

Дава съдържание за myJarFile.jar.

jar tvf myJarFile.jar

Добавя флаг за извеждане на по-подробни сведения за myJarFile.jar.

jar cvf myApp.jar audio classes image

Предполага се, че audio, classes и image са поддиректории, това комбинира всич­ко в поддиректориите във файл, наречен myApp.jar. ъщо се добавя флаг за по­вече обратна връзка докато програмата jar работи.

Ако създадете JAR чрез опцията O, този файл може да се сложи в CLASSPATH:

CLASSPATH="lib1.jar;lib2.jar;"

Тогава Java може да търси lib1.jar и lib2.jar за файлове с класове.

Инструментът jar не е толкова полезен калкото zip утилитито. Например не може да добавяте или обновявате файлове в JAR файл; може да създадете JAR фай­лове само "на празно място". Също не може да премествате файлове в JAR файл, изтривайки ги след вмъкването. Обаче един JAR файл създаден на ня­ка­ква платформа ще бъде прозрачно четим от jar инструмента на която и да е дру­га платформа (проблем, който понякога вади душата на zip ютилитата).

Както ще видите в глава 13, JAR файлове се използват и в пакета Java Beans.




Сподели с приятели:
1   ...   60   61   62   63   64   65   66   67   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница