[TOC] # éå½:æ°æ®å缩 Java I/O ç±»åºæä¾äºå¯ä»¥è¯»ååç¼©æ ¼å¼æµçç±»ãä½ å¯ä»¥å°å ¶ä» I/O ç±»å è£ èµ·æ¥ç¨äºæä¾å缩åè½ã è¿äºç±»ä¸æ¯ä» **Reader** å **Writer** 类派ççï¼èæ¯ **InputStream** å **OutputStream** å±çº§ç»æçä¸é¨åãè¿æ¯ç±äºå缩åºå¤ççæ¯åèï¼è䏿¯å符ã使¯ï¼ä½ å¯è½ä¼è¢«è¿«æ··å使ç¨ä¸¤ç§ç±»åçæµï¼è¯·è®°ä½ï¼ä½ å¯ä»¥ä½¿ç¨ **InputStreamReader** å **OutputStreamWriter**ï¼è¿ä¸¤ä¸ªç±»å¯ä»¥å¨åèç±»ååå符类åä¹é´è½»æ¾è½¬æ¢ï¼ã | å缩类 | åè½ | | ------------------------ | ------------------------------------------------------------ | | **CheckedInputStream** | `getCheckSum()` å¯ä»¥å¯¹ä»»æ **InputStream** è®¡ç®æ ¡éªåï¼èä¸åªæ¯è§£åï¼ | | **CheckedOutputStream** | `getCheckSum()` å¯ä»¥å¯¹ä»»æ **OutputStream** è®¡ç®æ ¡éªåï¼èä¸åªæ¯åç¼©ï¼ | | **DeflaterOutputStream** | å缩类çåºç±» | | **ZipOutputStream** | **DeflaterOutputStream** ç±»çä¸ç§ï¼ç¨äºåç¼©æ°æ®å° Zip æä»¶ç»æ | | **GZIPOutputStream** | **DeflaterOutputStream** ç±»çä¸ç§ï¼ç¨äºåç¼©æ°æ®å° GZIP æä»¶ç»æ | | **InflaterInputStream** | è§£åç±»çåºç±» | | **ZipInputStream** | **InflaterInputStream** ç±»çä¸ç§ï¼ç¨äºè§£å Zip æä»¶ç»æçæ°æ® | | **GZIPInputStream** | **InflaterInputStream** ç±»çä¸ç§ï¼ç¨äºè§£å GZIP æä»¶ç»æçæ°æ® | 尽管åå¨å¾å¤åç¼©ç®æ³ï¼ä½æ¯ Zip å GZIP å¯è½æ¯æå¸¸è§çãä½ å¯ä»¥ä½¿ç¨è®¸å¤ç¨äºè¯»åååå ¥è¿äºæ ¼å¼çå·¥å ·ï¼æ¥è½»æ¾æä½åç¼©æ°æ®ã ## ä½¿ç¨ Gzip ç®åå缩 GZIP æ¥å£ååç®åï¼å æ¤å½ä½ æä¸ä¸ªéè¦åç¼©çæ°æ®æµï¼è䏿¯ä¸ä¸ªå å«ä¸åæ°æ®åçç容å¨ï¼æ¶ï¼ä½¿ç¨ GZIP æ´ä¸ºåéãå¦ä¸æ¯ä¸ä¸ªå缩å个æä»¶ç示ä¾ï¼ ```java // compression/GZIPcompress.java // (c)2017 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. // {java GZIPcompress GZIPcompress.java} // {VisuallyInspectOutput} public class GZIPcompress { public static void main(String[] args) { if (args.length == 0) { System.out.println( "Usage: \nGZIPcompress file\n" + "\tUses GZIP compression to compress " + "the file to test.gz"); System.exit(1); } try ( InputStream in = new BufferedInputStream( new FileInputStream(args[0])); BufferedOutputStream out = new BufferedOutputStream( new GZIPOutputStream( new FileOutputStream("test.gz"))) ) { System.out.println("Writing file"); int c; while ((c = in.read()) != -1) out.write(c); } catch (IOException e) { throw new RuntimeException(e); } System.out.println("Reading file"); try ( BufferedReader in2 = new BufferedReader( new InputStreamReader(new GZIPInputStream( new FileInputStream("test.gz")))) ) { in2.lines().forEach(System.out::println); } catch (IOException e) { throw new RuntimeException(e); } } } ``` 使ç¨å缩类é常ç®åï¼ä½ åªéè¦æä½ çè¾åºæµå è£ å¨ **GZIPOutputStream** æ **ZipOutputStream** ä¸ï¼å°è¾å ¥æµå è£ å¨ **GZIPInputStream** æ **ZipInputStream**ãå ¶ä»çä¸åå°±åªæ¯æ®éç I/O 读åãè¿æ¯é¢åå符æµåé¢ååèæµçæ··å示ä¾ï¼in ä½¿ç¨ Reader ç±»ï¼è **GZIPOutputStreams** æé 彿°åªè½æ¥å **OutputStream** 对象ï¼èä¸è½æ¥å **Writer** 对象ãå½æå¼æä»¶çæ¶åï¼**GZIPInputStream** ä¼è½¬æ¢æä¸º **Reader**ã ## ä½¿ç¨ zip 夿件åå¨ æ¯æ Zip æ ¼å¼çåºæ¯ GZIP åºæ´å¹¿æ³ãæäºå®ï¼ä½ å¯ä»¥è½»æ¾åå¨å¤ä¸ªæä»¶ï¼çè³è¿æä¸ä¸ªåç¬çç±»å¯ä»¥è½»æ¾å°è¯»å Zip æä»¶ã该åºä½¿ç¨æ å Zip æ ¼å¼ï¼å æ¤å®å¯ä»¥ä¸å½åå¯å¨ Internet ä¸ä¸è½½çææ Zip å·¥å ·æ ç¼åä½ã以ä¸ç¤ºä¾ä¸åä¸ä¸ªç¤ºä¾å ·æç¸åçå½¢å¼ï¼ä½å®å¯ä»¥æ ¹æ®éè¦å¤çä»»ææ°éçå½ä»¤è¡åæ°ãæ¤å¤ï¼å®è¿æ¾ç¤ºäº **Checksum** 类计ç®åéªè¯æä»¶çæ ¡éªåãæä¸¤ç§æ ¡éªåç±»åï¼Adler32ï¼æ´å¿«ï¼å CRC32ï¼æ´æ ¢ä½æ´åç¡®ï¼ã ```java // compression/ZipCompress.java // (c)2017 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. // Uses Zip compression to compress any // number of files given on the command line // {java ZipCompress ZipCompress.java} // {VisuallyInspectOutput} public class ZipCompress { public static void main(String[] args) { try ( FileOutputStream f = new FileOutputStream("test.zip"); CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32()); ZipOutputStream zos = new ZipOutputStream(csum); BufferedOutputStream out = new BufferedOutputStream(zos) ) { zos.setComment("A test of Java Zipping"); // No corresponding getComment(), though. for (String arg : args) { System.out.println("Writing file " + arg); try ( InputStream in = new BufferedInputStream( new FileInputStream(arg)) ) { zos.putNextEntry(new ZipEntry(arg)); int c; while ((c = in.read()) != -1) out.write(c); } out.flush(); } // Checksum valid only after the file is closed! System.out.println( "Checksum: " + csum.getChecksum().getValue()); } catch (IOException e) { throw new RuntimeException(e); } // Now extract the files: System.out.println("Reading file"); try ( FileInputStream fi = new FileInputStream("test.zip"); CheckedInputStream csumi = new CheckedInputStream(fi, new Adler32()); ZipInputStream in2 = new ZipInputStream(csumi); BufferedInputStream bis = new BufferedInputStream(in2) ) { ZipEntry ze; while ((ze = in2.getNextEntry()) != null) { System.out.println("Reading file " + ze); int x; while ((x = bis.read()) != -1) System.out.write(x); } if (args.length == 1) System.out.println( "Checksum: " + csumi.getChecksum().getValue()); } catch (IOException e) { throw new RuntimeException(e); } // Alternative way to open and read Zip files: try ( 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 (IOException e) { throw new RuntimeException(e); } } } ``` 对äºè¦æ·»å å°åæ¡£çæ¯ä¸ªæä»¶ï¼å¿ é¡»è°ç¨ `putNextEntry()` å¹¶ä¼ é **ZipEntry** 对象ã **ZipEntry** 对象å å«ä¸ä¸ªæ©å±æ¥å£ï¼ç¨äºè·åå设置 Zip æä»¶ä¸è¯¥ç¹å®æ¡ç®çææå¯ç¨æ°æ®ï¼åç§°ï¼åç¼©åæªå缩大å°ï¼æ¥æï¼CRC æ ¡éªåï¼é¢å¤åæ®µæ°æ®ï¼æ³¨éï¼åç¼©æ¹æ³ä»¥å宿¯å¦æ¯ç®å½æ¡ç®ã使¯ï¼å³ä½¿ Zip æ ¼å¼æè®¾ç½®å¯ç çæ¹æ³ï¼Java ç Zip åºä¹ä¸æ¯æãè½ç¶ **CheckedInputStream** å **CheckedOutputStream** 齿¯æ Adler32 å CRC32 æ ¡éªåï¼ä½ **ZipEntry** ç±»ä» æ¯æ CRC æ¥å£ãè¿æ¯å¯¹åºç¡ Zip æ ¼å¼çéå¶ï¼ä½å®å¯è½ä¼éå¶ä½ ä½¿ç¨æ´å¿«ç Adler32ã è¦æåæä»¶ï¼**ZipInputStream** æä¸ä¸ª `getNextEntry()` æ¹æ³ï¼è¿ä¸ªæ¹æ³å¨ææä»¶åå¨çæ åµä¸è°ç¨ï¼ä¼è¿åä¸ä¸ä¸ª **ZipEntry**ãä½ä¸ºä¸ä¸ªæ´ç®æ´çæ¿ä»£æ¹æ³ï¼ä½ å¯ä»¥ä½¿ç¨ **ZipFile** 对象读å该æä»¶ï¼è¯¥å¯¹è±¡å ·ææ¹æ³ entries() è¿åä¸ä¸ªå 裹 **ZipEntries** ç **Enumeration**ã è¦è¯»åæ ¡éªåï¼ä½ å¿ é¡»ä»¥æç§æ¹å¼è®¿é®å ³èç **Checksum** 对象ãè¿éä¿çäºå¯¹ **CheckedOutputStream** å **CheckedInputStream** 对象çå¼ç¨ï¼ä½ä½ ä¹å¯ä»¥ä¿æå¯¹ **Checksum** 对象çå¼ç¨ã Zip æµä¸çä¸ä¸ªä»¤äººå°æçæ¹æ³æ¯ `setComment()`ãå¦ **ZipCompress** æç¤ºãå¨ Java ä¸ï¼ä½ å¯ä»¥å¨ç¼åæä»¶æ¶è®¾ç½®æ³¨éï¼ä½æ¯æ²¡æåæ³æ¢å¤ **ZipInputStream** ä¸ç注éãæ³¨éä¼¼ä¹ä» éè¿ **ZipEntry** å¨é个æ¡ç®çåºç¡ä¸å®å ¨æ¯æã ä½¿ç¨ GZIP æ Zip åºæ¶ï¼ä½ ä¸ä» 被éå¶äºæä»¶ââä½ å¯ä»¥å缩任ä½å 容ï¼å æ¬éè¿ç½ç»è¿æ¥åéçæ°æ®ã ## Java ç jar Zip æ ¼å¼ä¹ç¨äº JARï¼Java ARchiveï¼æä»¶æ ¼å¼ï¼è¿æ¯ä¸ç§å°ä¸ç»æä»¶æ¶éå°å个å缩æä»¶ä¸çæ¹æ³ï¼å°±å Zip 䏿 ·ã使¯ï¼ä¸ Java ä¸çå ¶ä»ææå 容䏿 ·ï¼JAR æä»¶æ¯è·¨å¹³å°çï¼å æ¤ä½ ä¸å¿ æ å¿å¹³å°é®é¢ãä½ è¿å¯ä»¥å°é³é¢åå¾åæä»¶åç±»æä»¶ä¸æ ·å å«å¨å ¶ä¸ã JAR æä»¶ç±ä¸ä¸ªå å«å缩æä»¶éåçæä»¶åä¸ä¸ªæè¿°å®ä»¬çâæ¸ åï¼manifestï¼âç»æãï¼ä½ å¯ä»¥å建èªå·±çæ¸ åæä»¶ï¼å¦åï¼jar ç¨åºå°ä¸ºä½ æ§è¡æ¤æä½ãï¼ä½ å¯ä»¥å¨ JDK ææ¡£ä¸ï¼æ¾å°æ´å¤å ³äº JAR æ¸ åçä¿¡æ¯ã JDK é带ç jar å·¥å ·ä¼èªå¨åç¼©ä½ éæ©çæä»¶ãä½ å¯ä»¥å¨å½ä»¤è¡ä¸è°ç¨å®ï¼ ```shell jar [options] destination [manifest] inputfile(s) ``` é项æ¯ä¸ç»åæ¯ï¼ä¸éè¦è¿å符æä»»ä½å ¶ä»æç¤ºç¬¦ï¼ã Unix / Linux ç¨æ·ä¼æ³¨æå°è¿äºéé¡¹ä¸ tar å½ä»¤é项çç¸ä¼¼æ§ãè¿äºæ¯ï¼ | é项 | åè½ | | ---------- | ------------------------------------------------------------ | | **c** | å建ä¸ä¸ªæ°çæè 空ç彿¡£æä»¶ | | **t** | ååºå 容ç®å½ | | **x** | æåæææä»¶ | | **x** file | æåæå®çæä»¶ | | **f** | è¿ä»£è¡¨çï¼âä¼ éæä»¶çåç§°ãâå¦æä½ ä¸ä½¿ç¨å®ï¼jar åå®å®çè¾å ¥å°æ¥èªæ åè¾å ¥ï¼æè ï¼å¦æå®æ£å¨å建ä¸ä¸ªæä»¶ï¼å®çè¾åºå°è½¬å°æ åè¾åºã | | **m** | 代表第ä¸ä¸ªåæ°æ¯ç¨æ·åå»ºçæ¸ åæä»¶çåç§°ã | | **v** | çæè¯¦ç»çè¾åºç¨äºè¡¨è¿° jar æä½çäºæ | | **0** | ä» å卿件;ä¸å缩æä»¶ï¼ç¨äºå建æ¾å¨ç±»è·¯å¾ä¸ç JAR æä»¶ï¼ã | | **M** | ä¸è¦èªå¨åå»ºæ¸ åæä»¶ | 妿æ¾å ¥ JAR æä»¶çæä»¶ä¸å å«åç®å½ï¼åä¼èªå¨æ·»å 该åç®å½ï¼å æ¬å ¶ææåç®å½çãè¿ä¼ä¿çè·¯å¾ä¿¡æ¯ã 以䏿¯ä¸äºè°ç¨ jar çå ¸åæ¹æ³ã以ä¸å½ä»¤å建å为 myJarFile ç JAR æä»¶ã jar å å«å½åç®å½ä¸çææç±»æä»¶ï¼ä»¥åèªå¨çæçæ¸ åæä»¶ï¼ ```shell jar cf myJarFile.jar *.class ``` ä¸ä¸ä¸ªå½ä»¤ä¸åé¢ç示ä¾ç±»ä¼¼ï¼ä½å®æ·»å äºä¸ä¸ªå为 myManifestFile.mf çç¨æ·åå»ºçæ¸ åæä»¶ã ï¼ ```shell jar cmf myJarFile.jar myManifestFile.mf *.class ``` è¿ä¸ªå½ä»¤è¾åºäº myJarFile.jar ä¸çæä»¶ç®å½ï¼ ```shell jar tf myJarFile.jar ``` å¦ä¸æ·»å äºä¸ä¸ªâverboseâçæ å¿ï¼ç¨äºçææ´å¤å ³äº myJarFile.jar 䏿件ç详ç»ä¿¡æ¯ï¼ ```shell jar tvf myJarFile.jar ``` å设 audioï¼classes å image 齿¯åç®å½ï¼å®å°ææåç®å½ç»åå°æä»¶ myApp.jar ä¸ãè¿å æ¬âverboseâæ å¿ï¼ä»¥ä¾¿å¨ jar ç¨åºå·¥ä½æ¶æä¾é¢å¤çåé¦ï¼ ```shell jar cvf myApp.jar audio classes image ``` å¦æä½ å¨å建 JAR æä»¶æ¶ä½¿ç¨äº 0ï¼é¶ï¼ é项ï¼è¯¥æä»¶å°ä¼è¢«æ¿æ¢å¨ä½ ç类路å¾ï¼CLASSPATHï¼ä¸ï¼ ```shell CLASSPATH="lib1.jar;lib2.jar;" ``` ç¶å Java å¯ä»¥æç´¢å° lib1.jar å lib2.jar çç±»æä»¶ã jar å·¥å ·ä¸å Zip å®ç¨ç¨åºé£æ ·éç¨ãä¾å¦ï¼ä½ æ æ³å°æä»¶æ·»å ææ´æ°å°ç°æ JAR æä»¶ï¼åªè½ä»å¤´å¼å§å建 JAR æä»¶ã æ¤å¤ï¼ä½ æ æ³å°æä»¶ç§»å¨å° JAR æä»¶ä¸ï¼å¨ç§»å¨æä»¶æ¶å°å ¶å é¤ã 使¯ï¼å¨ä¸ä¸ªå¹³å°ä¸å建ç JAR æä»¶å¯ä»¥éè¿ä»»ä½å ¶ä»å¹³å°ä¸ç jar å·¥å ·éæå°è¯»åï¼è¿ä¸ªé®é¢ææ¶ä¼å°æ° Zip å®ç¨ç¨åºï¼ã