利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)地壓縮與解壓縮_第1頁(yè)
利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)地壓縮與解壓縮_第2頁(yè)
利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)地壓縮與解壓縮_第3頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、WORD格式PAGE1 / NUMPAGES18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮2002年2月本文通過(guò)對(duì)數(shù)據(jù)壓縮算法的簡(jiǎn)要介紹,然后以詳細(xì)的示例演示了利用java.util.zip包實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓,并擴(kuò)展到在網(wǎng)絡(luò)傳輸方面如何應(yīng)用java.util.zip包現(xiàn)數(shù)據(jù)壓縮與解壓綜述許多信息資料都或多或少的包含一些多余的數(shù)據(jù)。通常會(huì)導(dǎo)致在客戶端與服務(wù)器之間,應(yīng)用程序與計(jì)算機(jī)之間極大的數(shù)據(jù)傳輸量。最常見(jiàn)的解決數(shù)據(jù)存儲(chǔ)和信息傳送的方法是安裝額外的存儲(chǔ)設(shè)備和擴(kuò)展現(xiàn)有的通訊能力。這樣做是可以的,但無(wú)疑會(huì)增加組織的運(yùn)作成本。一種有效的解決數(shù)據(jù)存儲(chǔ)與信

2、息傳輸?shù)姆椒ㄊ峭ㄟ^(guò)更有效率的代碼來(lái)存儲(chǔ)數(shù)據(jù)。這篇文章簡(jiǎn)要的介紹了數(shù)據(jù)的壓縮與解壓縮,并展示了用java.util.zip包來(lái)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮是多么的方便與高效。當(dāng)然用諸如WinZip,gzip,和Java壓縮(或jar)之類(lèi)的工具也可以實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮,這些工具都是獨(dú)立的應(yīng)用程序。你也可以在JAVA應(yīng)用程序中調(diào)用這些工具,但這并不是最直接的方法,也不是有效的解決方法。尤其是你想更快速地實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮(例如在傳輸數(shù)據(jù)到遠(yuǎn)程機(jī)器之前)。這篇文章包括以下內(nèi)容:給出一個(gè)關(guān)于數(shù)據(jù)壓縮的簡(jiǎn)單的介紹描述java.util.zip包示例如何使用該包實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮示例如何壓縮串行化的

3、對(duì)象并將其存儲(chǔ)在磁碟上示例如何通過(guò)數(shù)據(jù)壓縮來(lái)增強(qiáng)客戶/服務(wù)應(yīng)用程序的性能數(shù)據(jù)壓縮概述文件中數(shù)據(jù)冗余的最簡(jiǎn)單的類(lèi)型是字符的復(fù)制。讓我們先來(lái)看下面一個(gè)字符串:JJJJJJAAAAVVVVAAAAAA這個(gè)字符串可以用更簡(jiǎn)潔的方式來(lái)編碼,那就是通過(guò)替換每一個(gè)重復(fù)的字符串為單個(gè)的實(shí)例字符加上記錄重復(fù)次數(shù)的數(shù)字來(lái)表示,上面的字符串可以被編碼為下面的形式:1/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮6J4A4V6A在這里,6J意味著6個(gè)字符J,4A意味著4個(gè)字符A,以此類(lèi)推。這種字符串壓縮方式稱為行程長(zhǎng)度編碼方式,簡(jiǎn)稱RLE。再舉一個(gè)例子,考慮一下矩形圖像的存儲(chǔ)。一個(gè)單色位圖,可以被存儲(chǔ)為下面這種形

4、式,如圖1所示。圖1:RLE方式下的位圖信息另外一種方式是將圖像存為一個(gè)圖元文件:Rectangle11,3,20,5上面的表示方法是講矩形的起始坐標(biāo)是(11,3),寬度是20,高度是5。上述的矩形圖像可以使用RLE編碼方式壓縮,通過(guò)對(duì)相同位記數(shù)表示如下:0,400,400,101,200,100,101,10,181,10,100,101,10,181,10,100,101,10,181,10,100,101,200,100,40上面第一行是講圖像的第一行由40個(gè)0組成。第三行是講圖像的第三行是由10個(gè)0加上20個(gè)1再加上10個(gè)0組成,其它行以此類(lèi)推。2/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的

5、壓縮與解壓縮大家注意,RLE方法需要將其表示的文件與編碼文件分開(kāi)。所以,這種方法不能應(yīng)用于所有的文件。其它的壓縮技術(shù)包括變長(zhǎng)編碼(也被稱為哈夫曼編碼),還有其它的方法。要想了解更詳細(xì)的信息,請(qǐng)參考有關(guān)數(shù)據(jù)和圖像壓縮技術(shù)方面的圖書(shū),一定會(huì)有收獲的。數(shù)據(jù)壓縮有很多益處。不管怎么說(shuō),最主要的好處就是減少存儲(chǔ)方面的需求。同樣的,對(duì)于數(shù)據(jù)通信來(lái)講,壓縮數(shù)據(jù)在媒體中的將導(dǎo)致信息傳輸數(shù)據(jù)的提升。數(shù)據(jù)的壓縮能夠通過(guò)軟件在現(xiàn)有的硬件設(shè)備上實(shí)現(xiàn)或者通過(guò)帶有壓縮技術(shù)的特殊的硬件設(shè)備來(lái)實(shí)現(xiàn)。圖表2顯示了基本的數(shù)據(jù)壓縮結(jié)構(gòu)圖。圖2:數(shù)據(jù)壓縮結(jié)構(gòu)圖ZIPVSGZIP如果你是在Windows系統(tǒng)下工作,你可能會(huì)對(duì)工具Win

6、Zip很熟悉,是用來(lái)創(chuàng)建壓縮檔案和解開(kāi)壓縮檔案的。而在UNIX平臺(tái)上,會(huì)有一些不同,命令tar用來(lái)創(chuàng)建一個(gè)檔案文件(并不壓縮),其它的程序(gzip或compress)用來(lái)創(chuàng)建一個(gè)壓縮檔案。WinZip和PkZip之類(lèi)的工具同時(shí)扮演著歸檔和壓縮兩個(gè)角色。他們將文件壓縮并將其歸檔。另一方面,gzip并不將文件歸檔。所以,在UNIX平臺(tái)上,命令tar通常用來(lái)創(chuàng)建一個(gè)檔案文件,然后命令gzip來(lái)將檔案文件壓縮。Java.util.zip包Java提供了java.util.zip包用來(lái)兼容ZIP格式的數(shù)據(jù)壓縮。它提供了一系列的類(lèi)用來(lái)讀取,創(chuàng)建,修改ZIP和GZIP格式的文件。它還提供了工具類(lèi)來(lái)計(jì)算任意

7、輸入流的數(shù)目,這可以用來(lái)驗(yàn)證輸入數(shù)據(jù)的有效性。該包提供了一個(gè)接口,十四個(gè)類(lèi),和兩個(gè)異常處理類(lèi),如表1所示。表1:java.util.zip包條目類(lèi)型描述3/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮Checksum接口被類(lèi)Adler32和CRC32實(shí)現(xiàn)的接口Adler32類(lèi)使用Alder32算法來(lái)計(jì)算Checksum數(shù)目CheckedInputStream類(lèi)一個(gè)輸入流,保存著被讀取數(shù)據(jù)的ChecksumCheckedOutputStream類(lèi)一個(gè)輸出流,保存著被讀取數(shù)據(jù)的ChecksumCRC32類(lèi)使用CRC32算法來(lái)計(jì)算Checksum數(shù)目Deflater類(lèi)使用ZLIB壓縮類(lèi),支持通常

8、的壓縮方式DeflaterOutputStream類(lèi)一個(gè)輸出過(guò)濾流,用來(lái)壓縮Deflater格式數(shù)據(jù)GZIPInputStream類(lèi)一個(gè)輸入過(guò)濾流,讀取GZIP格式壓縮數(shù)據(jù)GZIPOutputStream類(lèi)一個(gè)輸出過(guò)濾流,讀取GZIP格式壓縮數(shù)據(jù)Inflater類(lèi)使用ZLIB壓縮類(lèi),支持通常的解壓方式InlfaterInputStream類(lèi)一個(gè)輸入過(guò)濾流,用來(lái)解壓Inlfater格式的壓縮數(shù)據(jù)ZipEntry類(lèi)存儲(chǔ)ZIP條目ZipFile類(lèi)從ZIP文件中讀取ZIP條目ZipInputStream類(lèi)一個(gè)輸入過(guò)濾流,用來(lái)讀取ZIP格式文件中的文件ZipOutputStream類(lèi)一個(gè)輸出過(guò)濾流,用來(lái)

9、向ZIP格式文件口寫(xiě)入文件DataFormatException異常類(lèi)拋出一個(gè)數(shù)據(jù)格式錯(cuò)誤ZipException異常類(lèi)拋出一個(gè)ZIP文件注意:ZLIB壓縮類(lèi)最初是作為可移植的網(wǎng)絡(luò)圖像文件格式(PNG)標(biāo)準(zhǔn)的一部分開(kāi)發(fā)的,是不受專利保護(hù)的。從ZIP文件中解壓縮和提取數(shù)據(jù)java.util.zip包提供了數(shù)據(jù)壓縮與解壓縮所需要的類(lèi)。ZIP文件的解壓縮實(shí)質(zhì)上就是從輸入流中讀取數(shù)據(jù)。Java.util.zip包提供了類(lèi)ZipInputStream來(lái)讀取ZIP文件。ZipInputStream流的創(chuàng)建與其它輸入流的創(chuàng)建沒(méi)什么兩樣。舉個(gè)例子,下面的代碼段創(chuàng)建了一個(gè)輸入流來(lái)讀取ZIP格式的文件:FileI

10、nputStreamfis=newFileInputStream(figs.zip);ZipInputStreamzin=newZipInputStream(newBufferedInputStream(fis);ZIP輸入流打開(kāi)后,你可以使用getNextEntry方法來(lái)讀取ZIP文件中的條目數(shù),該方法返回一個(gè)ZipEntry對(duì)象。如果到達(dá)文件的尾部,getNextEntry返回null:ZipEntryentry;4/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮while(entry=zin.getNextEntry()!=null)/extractdata/openoutputstr

11、eams現(xiàn)在,你應(yīng)該建立一個(gè)輸出流,如下所示:intBUFFER=2048;FileOutputStreamfos=newFileOutputStream(entry.getName();BufferedOutputStreamdest=newBufferedOutputStream(fos,BUFFER);注意:在這段代碼中我們用BufferedOutputStream代替了ZIPOutputStream。ZIPOutputStream和GZIPOutputStream使用內(nèi)置的512字節(jié)緩沖。當(dāng)緩沖區(qū)的大小大于512字節(jié)時(shí),使用BufferedOutputStream才是正確的(例子中設(shè)置

12、為2048)。ZIPOutputStream不允許你設(shè)置緩沖區(qū)的大小,GZIPOutputStream也是一樣,但創(chuàng)建GZIPOutputStream對(duì)象時(shí)可以通過(guò)構(gòu)造函數(shù)的參數(shù)指定內(nèi)置的緩沖尺寸。這段代碼中,使用ZIP內(nèi)含的條目名稱創(chuàng)建一個(gè)文件輸出流??梢允褂胑ntry.getName來(lái)得到它的返回句柄。接著讀出被壓縮的源數(shù)據(jù),然后寫(xiě)入輸出流:while(count=zin.read(data,0,BUFFER)!=-1)/System.out.write(x);dest.write(data,0,count);最后,不要忘記關(guān)閉輸入和輸出流:dest.flush();dest.close(

13、);zin.close();5/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮例程1的源程序UnZip.java顯示如何解壓縮并從ZIP檔案中將文件釋放出來(lái)。測(cè)試這個(gè)例子,編譯這個(gè)類(lèi),并運(yùn)行它,傳給它一個(gè)ZIP格式的文件作為參數(shù):promptjavaUnZipsomefile.zip注意:somefile.zip應(yīng)該是一個(gè)ZIP壓縮檔案,可以用任何一種ZIP壓縮工具來(lái)創(chuàng)建,例如WinZip。例程1源代碼:UnZip.javaimportjava.io.*;importjava.util.zip.*;publicclassUnZipstaticfinalintBUFFER=2048;publi

14、cstaticvoidmain(Stringargv)tryBufferedOutputStreamdest=null;FileInputStreamfis=newFileInputStream(argv0);ZipInputStreamzis=newZipInputStream(newBufferedInputStream(fis);ZipEntryentry;while(entry=zis.getNextEntry()!=null)System.out.println(Extracting:+entry);intcount;bytedata=newbyteBUFFER;/writethef

15、ilestothediskFileOutputStreamfos=newFileOutputStream(entry.getName();dest=newBufferedOutputStream(fos,BUFFER);while(count=zis.read(data,0,BUFFER)!=-1)dest.write(data,0,count);dest.flush();dest.close();zis.close();catch(Exceptione)6/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮e.printStackTrace();有一點(diǎn)值得大家注意,類(lèi)ZipInputStrea

16、m讀出ZIP文件序列(簡(jiǎn)單地說(shuō)就是讀出這個(gè)ZIP文件壓縮了多少文件),而類(lèi)ZipFile使用內(nèi)嵌的隨機(jī)文件訪問(wèn)機(jī)制讀出其中的文件內(nèi)容,所以不必順序的讀出ZIP壓縮文件序列。注意:ZIPInputStream和ZipFile之間另外一個(gè)基本的不同點(diǎn)在于高速緩沖的使用方面。當(dāng)文件使用ZipInputStream和FileInputStream流讀出的時(shí)候,ZIP條目不使用高速緩沖。然而,如果使用ZipFile(文件名)來(lái)打開(kāi)文件,它將使用內(nèi)嵌的高速緩沖,所以如果ZipFile(文件名)被重復(fù)調(diào)用的話,文件只被打開(kāi)一次。緩沖值在第二次打開(kāi)進(jìn)使用。如果你工作在UNIX系統(tǒng)下,這是什么作用都沒(méi)有的,因?yàn)?/p>

17、使用ZipFile打開(kāi)的所有ZIP文件都在內(nèi)存中存在映射,所以使用ZipFile的性能優(yōu)于ZipInputStream。然而,如果同一ZIP文件的內(nèi)容在程序執(zhí)行期間經(jīng)常改變,或是重載的話,使用ZipInputStream就成為你的首選了。下面顯示了使用類(lèi)ZipFile來(lái)解壓一個(gè)ZIP文件的過(guò)程:1.通過(guò)指定一個(gè)被讀取的ZIP文件,或者是文件名,或者是一個(gè)文件對(duì)象來(lái)創(chuàng)建一個(gè)ZipFile對(duì)象:ZipFilezipfile=newZipFile(figs.zip);2.使用entries方法,返回一個(gè)枚舉對(duì)象,循環(huán)獲得文件的ZIP條目對(duì)象:while(e.hasMoreElements()entr

18、y=(ZipEntry)e.nextElement();/readcontentsandsavethem3.ZIP條目作為參數(shù)傳遞給getInputStream方法,可以讀取ZIP文件中指定條目的內(nèi)容,能過(guò)其返回的輸入流(InputStram)對(duì)象可以方便的讀出ZIP條目的內(nèi)容:is=newBufferedInputStream(zipfile.getInputStream(entry);7/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮4.獲取ZIP條目的文件名,創(chuàng)建輸出流,并保存:bytedata=newbyteBUFFER;FileOutputStreamfos=newFileOutp

19、utStream(entry.getName();dest=newBufferedOutputStream(fos,BUFFER);while(count=is.read(data,0,BUFFER)!=-1)dest.write(data,0,count);5.最后關(guān)閉所有的輸入輸出流dest.flush();dest.close();is.close();完整的程序代碼如例程2所示。再次編譯這個(gè)文件,并傳遞一個(gè)ZIP格式的文件做為參數(shù):promptjavaUnZip2somefile.zip例程2源碼:UnZip2.javaimportjava.io.*;importjava.util.*

20、;importjava.util.zip.*;publicclassUnZip2staticfinalintBUFFER=2048;publicstaticvoidmain(Stringargv)tryBufferedOutputStreamdest=null;BufferedInputStreamis=null;ZipEntryentry;ZipFilezipfile=newZipFile(argv0);Enumeratione=zipfile.entries();while(e.hasMoreElements()entry=(ZipEntry)e.nextElement();System.

21、out.println(Extracting:+entry);is=newBufferedInputStream(zipfile.getInputStream(entry);intcount;8/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮bytedata=newbyteBUFFER;FileOutputStreamfos=newFileOutputStream(entry.getName();dest=newBufferedOutputStream(fos,BUFFER);while(count=is.read(data,0,BUFFER)!=-1)dest.write(data,0,c

22、ount);dest.flush();dest.close();is.close();catch(Exceptione)e.printStackTrace();將數(shù)據(jù)壓縮歸檔入一ZIP文件類(lèi)ZipOutputStream能夠用來(lái)將數(shù)據(jù)壓縮成一個(gè)ZIP文件。ZipOutputStream將數(shù)據(jù)寫(xiě)入ZIP格式的輸出流。下面的步驟與創(chuàng)建一個(gè)ZIP文件相關(guān)。1、第一步是創(chuàng)建一個(gè)ZipOutputStream對(duì)象,我們將要寫(xiě)入輸出流的文件作為參數(shù)傳給它。下面的代碼演示了如何創(chuàng)建一個(gè)名為myfigs.zip的ZIP文件。FileOutputStreamdest=newFileOutputStream(my

23、figs.zip);ZipOutputStreamout=newZipOutputStream(newBufferedOutputStream(dest);2、一但目標(biāo)輸出流創(chuàng)建后,下一步就是打開(kāi)數(shù)據(jù)源文件。在這個(gè)例子中,源數(shù)據(jù)文件是指那些當(dāng)前目錄下的文件。命令list用來(lái)得到當(dāng)前目錄下文件列表:Filef=newFile(.);Stringfiles=f.list();for(inti=0;ifiles.length;i+)9/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮System.out.println(Adding:+filesi);FileInputStreamfi=newFil

24、eInputStream(filesi);/createzipentry/addentriestoZIPfile注意:這個(gè)例程能夠壓縮當(dāng)前目錄下的所有文件。它不能處理子目錄。作為一個(gè)練習(xí),你可以修改例程3來(lái)處理子目錄。3、為讀出的數(shù)據(jù)創(chuàng)建一個(gè)ZIP條目列表:ZipEntryentry=newZipEntry(filesi)4、在你將數(shù)據(jù)寫(xiě)入ZIP輸出流之前,你必須使用putNextEntry方法將ZIP條目列表寫(xiě)入輸出流:out.putNextEntry(entry);5、將數(shù)據(jù)寫(xiě)入ZIP文件:intcount;while(count=origin.read(data,0,BUFFER)!=-

25、1)out.write(data,0,count);6、最后關(guān)閉所有的輸入輸出流:origin.close();out.close();完整的程序代碼如例程3所示。例程3源代碼:Zip.javaimportjava.io.*;importjava.util.zip.*;publicclassZipstaticfinalintBUFFER=2048;10/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮publicstaticvoidmain(Stringargv)tryBufferedInputStreamorigin=null;FileOutputStreamdest=newFileOutp

26、utStream(c:zipmyfigs.zip);ZipOutputStreamout=newZipOutputStream(newBufferedOutputStream(dest);/out.setMethod(ZipOutputStream.DEFLATED);bytedata=newbyteBUFFER;/getalistoffilesfromcurrentdirectoryFilef=newFile(.);Stringfiles=f.list();for(inti=0;ifiles.length;i+)System.out.println(Adding:+filesi);FileI

27、nputStreamfi=newFileInputStream(filesi);origin=newBufferedInputStream(fi,BUFFER);ZipEntryentry=newZipEntry(filesi);out.putNextEntry(entry);intcount;while(count=origin.read(data,0,BUFFER)!=-1)out.write(data,0,count);origin.close();out.close();catch(Exceptione)e.printStackTrace();注意:條目列表可以以兩種方式加入ZIP文件

28、中,一種是壓縮方式(DEFLATED),另一種是不壓縮方式(STORED),系統(tǒng)默認(rèn)的存儲(chǔ)方式為壓縮方式(DEFLATED)。SetMethod方法可以用來(lái)設(shè)置它的存儲(chǔ)方式。例如,設(shè)置存儲(chǔ)方式為DEFLATED(壓縮)應(yīng)該這樣做:out.setMethod(ZipOutputStream.DEFLATED)設(shè)置存儲(chǔ)方式為(不壓縮)應(yīng)該這樣做:out.setMethod(ZipOutputStream.STORED)。11/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮ZIP文件屬性類(lèi)ZipEntry描述了存儲(chǔ)在ZIP文件中的壓縮文件。類(lèi)中包含有多種方法可以用來(lái)設(shè)置和獲得ZIP條目的信息。類(lèi)Z

29、ipEntry是被ZipFile和ZipInputStream使用來(lái)讀取ZIP文件,ZipOutputStream來(lái)寫(xiě)入ZIP文件的。ZipEntry中最有用的一些方法顯示在下面的表格2中,并且有相應(yīng)的描述。表格2:類(lèi)ZipEntry中一些有用的方法方法簽名描述publicStringgetComment()返回條目的注釋,沒(méi)有返回nullpubliclonggetCompressedSize()返回條目壓縮后的大小,未知返回-1publicintgetMethod()返回條目的壓縮方式,沒(méi)有指定返回-1publicStringgetName()返回條目的名稱publiclonggetSize

30、()返回未被壓縮的條目的大小,未知返回-1publiclonggetTime()返回條目的修改時(shí)間,沒(méi)有指定返回-1publicvoidsetComment(Stringc)設(shè)置條目的注釋publicvoidsetMethod(intmethod)設(shè)置條目的壓縮方式publicvoidsetSize(longsize)設(shè)置沒(méi)有壓縮的條目的大小publicvoidsetTime(longtime)設(shè)置條目的修改時(shí)間求和校驗(yàn)java.util.zip包中另外一些比較重要的類(lèi)是Adler32和CRC32,它們實(shí)現(xiàn)了java.util.zip.Checksum接口,并估算了壓縮數(shù)據(jù)的校驗(yàn)和(check

31、sum)。眾所周知,在運(yùn)算速度方面,Adler32算法比CRC32算法要有一定的優(yōu)勢(shì);但在數(shù)據(jù)可信度方面,CRC32算法則要更勝一籌。正所謂,魚(yú)與熊掌,不可兼得。,大家只好在不同的場(chǎng)合下,加以取舍了。GetValue方法可以用來(lái)獲得當(dāng)前的checksum值,reset方法能夠重新設(shè)置checksum為其缺省的值。求和校驗(yàn)一般用來(lái)校驗(yàn)文件和信息是否正確的傳送。舉個(gè)例子,假設(shè)你想創(chuàng)建一個(gè)ZIP文件,然后將其傳送到遠(yuǎn)程計(jì)算機(jī)上。當(dāng)?shù)竭_(dá)遠(yuǎn)程計(jì)算機(jī)后,你就可以使用checksum檢驗(yàn)在傳輸過(guò)程中文件是否發(fā)生錯(cuò)誤。為了演示如何創(chuàng)建checksums,我們修改了例程1和例程3,在例程4和例程5中使用了兩個(gè)新

32、類(lèi),一個(gè)是CheckedInputStream,另一個(gè)是CheckedOutputStream。(大家注意:這兩段代碼在壓縮與解壓縮過(guò)程中,使用了同一種算法,求數(shù)據(jù)的checksum值。)例程4源代碼:12/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮Zip.javaimportjava.io.*;importjava.util.zip.*;publicclassZipstaticfinalintBUFFER=2048;publicstaticvoidmain(Stringargv)tryBufferedInputStreamorigin=null;FileOutputStreamdest

33、=newFileOutputStream(c:zipmyfigs.zip);CheckedOutputStreamchecksum=newCheckedOutputStream(dest,newAdler32();ZipOutputStreamout=newZipOutputStream(newBufferedOutputStream(checksum);/out.setMethod(ZipOutputStream.DEFLATED);bytedata=newbyteBUFFER;/getalistoffilesfromcurrentdirectoryFilef=newFile(.);Stri

34、ngfiles=f.list();for(inti=0;ifiles.length;i+)System.out.println(Adding:+filesi);FileInputStreamfi=newFileInputStream(filesi);origin=newBufferedInputStream(fi,BUFFER);ZipEntryentry=newZipEntry(filesi);out.putNextEntry(entry);intcount;while(count=origin.read(data,0,BUFFER)!=-1)out.write(data,0,count);

35、origin.close();out.close();System.out.println(checksum:+checksum.getChecksum().getValue();catch(Exceptione)e.printStackTrace();13/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮例程5源代碼:UnZip.javaimportjava.io.*;importjava.util.zip.*;publicclassUnZippublicstaticvoidmain(Stringargv)tryfinalintBUFFER=2048;BufferedOutputStream

36、dest=null;FileInputStreamfis=newFileInputStream(argv0);CheckedInputStreamchecksum=newCheckedInputStream(fis,newAdler32();ZipInputStreamzis=newZipInputStream(newBufferedInputStream(checksum);ZipEntryentry;while(entry=zis.getNextEntry()!=null)System.out.println(Extracting:+entry);intcount;bytedata=new

37、byteBUFFER;/writethefilestothediskFileOutputStreamfos=newFileOutputStream(entry.getName();dest=newBufferedOutputStream(fos,BUFFER);while(count=zis.read(data,0,BUFFER)!=-1)dest.write(data,0,count);dest.flush();dest.close();zis.close();System.out.println(Checksum:+checksum.getChecksum().getValue();cat

38、ch(Exceptione)14/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮e.printStackTrace();測(cè)試?yán)?和5,編譯類(lèi)文件并運(yùn)行類(lèi)Zip來(lái)創(chuàng)建一個(gè)壓縮檔案(程序會(huì)計(jì)算出checksum值并顯示在屏幕上),然后運(yùn)行UnZip類(lèi)來(lái)解壓縮這個(gè)檔案(屏幕上同樣會(huì)打印出一個(gè)checksum值)。兩個(gè)值必須完全相同,否則說(shuō)明出錯(cuò)了。Checksums在數(shù)據(jù)校驗(yàn)方面非常有用。例如,你可以創(chuàng)建一個(gè)ZIP文件,然后連同checksum值一同傳遞給你的朋友。你的朋友解壓縮文件后,將生成的checksum值與你提供的作一比較,如果相同則說(shuō)明在傳遞過(guò)程中沒(méi)有發(fā)生錯(cuò)誤。壓縮對(duì)象我們已經(jīng)看到如何

39、將文件中的數(shù)據(jù)壓縮并將其歸檔。但如果你想壓縮的數(shù)據(jù)不在文件中時(shí),應(yīng)該怎么辦呢?假設(shè)有這樣一個(gè)例子,你通過(guò)套接字(socket)來(lái)傳遞一個(gè)大對(duì)象。為了提高應(yīng)用程序的性能,你可能在通過(guò)網(wǎng)絡(luò)開(kāi)始傳遞前將數(shù)據(jù)壓縮,然后在目的地將其解壓縮。另外一個(gè)例子,我們假設(shè)你想將一個(gè)對(duì)象用壓縮格式存儲(chǔ)在磁碟上,ZIP格式是基于記錄方式的,不適合這項(xiàng)工作。GZIP更適合用來(lái)實(shí)現(xiàn)這種對(duì)單一數(shù)據(jù)流的操作?,F(xiàn)在,我們來(lái)示例一下,如果在寫(xiě)入磁碟前將數(shù)據(jù)壓縮,并在讀出時(shí)將數(shù)據(jù)解壓縮。示例程序6是一個(gè)在單一JVM(java虛擬機(jī))實(shí)現(xiàn)了Serializable接口的簡(jiǎn)單類(lèi),我們想要串行化該類(lèi)的實(shí)例。例程6源代碼:Employee

40、.javaimportjava.io.*;publicclassEmployeeimplementsSerializableStringname;intage;intsalary;publicEmployee(Stringname,intage,intsalary)=name;this.age=age;15/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮this.salary=salary;publicvoidprint()System.out.println(Recordfor:+name);System.out.println(Name:+name);System.out.println

41、(Age:+age);System.out.println(Salary:+salary);現(xiàn)在,寫(xiě)另外一個(gè)類(lèi)來(lái)創(chuàng)建兩個(gè)從Employee類(lèi)實(shí)例化而來(lái)的對(duì)象。示例程序7從Employee類(lèi)創(chuàng)建了兩個(gè)對(duì)象(sarah和sam)。然后將它們的狀態(tài)以壓縮的格式存儲(chǔ)在一個(gè)文件中。示例程序7源代碼:SaveEmployee.javaimportjava.io.*;importjava.util.zip.*;publicclassSaveEmployeepublicstaticvoidmain(Stringargv)throwsException/createsomeobjectsEmployeesara

42、h=newEmployee(S.Jordan,28,56000);Employeesam=newEmployee(S.McDonald,29,58000);/serializetheobjectssarahandsamFileOutputStreamfos=newFileOutputStream(db);GZIPOutputStreamgz=newGZIPOutputStream(fos);ObjectOutputStreamoos=newObjectOutputStream(gz);oos.writeObject(sarah);oos.writeObject(sam);oos.flush();oos.close();fos.close();16/18利用JAVAAPI函數(shù)實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮現(xiàn)在,示例程序8中的ReadEmpolyee類(lèi)是用來(lái)重新構(gòu)建兩個(gè)對(duì)象的狀態(tài)。一但構(gòu)建成功,就調(diào)用print方法將

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論