From: http://www.cnjm.net/tech/article4729.html
The super short and concise zip decompression class has only 280 lines of Java code. After obfuscation and compression, the class file is only about 4 K, which is especially suitable for the development of j2s.
The decompression algorithm comes from the famous gzip. Java on the Internet. I only added the Section for parsing the ZIP file format.
List () method:
List all files and directories in the zip package, including the full name of the path, for example, the file "dir1/dir2/file.txt", or the directory "dir1/dir2 /", note that the path separator is a forward slash '/', and the last character of the directory must be '/'.
Get (string filename) method:
Extract the file with the specified name from the zip package and return the byte array.
Zipme (inputstream is ):
Read the ZIP file from an input stream. It can be a file in the jar package, a file in the mobile phone file system obtained through fileconnection, or a zip package downloaded from the network.
The following sample code accesses the ZIP file in the jar package and decompress all the files in the package one by one:
Inputstream is = "". getclass (). getresourceasstream ("/RES/test.zip ");
Zipme file = new zipme (is );
Is. Close ();
Vector p = file. List ();
For (INT I = 0; I <p. Size (); I ++ ){
String name = (string) p. Get (I );
Byte [] BB = file. Get (name );
System. Out. println ("file:" + name + "/data_len:" + (BB! = NULL? BB. Length:-1 ));
}
========================================================== ================
Package net. cnjm. j2s. utils; </P> <p> Import Java. io. *; <br/> Import Java. util. *; </P> <p> public class zipme {</P> <p> Private Static final int btype_none = 0; <br/> Private Static final int btype_dynamic = 2; <br/> Private Static final int max_bits = 16; <br/> Private Static final int max_code_literals = 287; <br/> Private Static final int max_code_distances = 31; <br/> Private Static final int max_code _ Lengths = 18; <br/> Private Static final int eob_code = 256; </P> <p> Private Static final int length_extra_bits [] = {0, 0, 0, 0, 0, 0, 0, 0, 1, <br/> 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99 }; <br/> Private Static final int length_values [] = {3, 4, 5, 6, 7, 8, 9, 10, 11, <br/> 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99,115,131, <br/> 163,195,227,258, 0, 0 }; <br/> Private Static final int distance_extra_bits [] = {0, 0, 0, 0, 1, 1, 2, 2, <br/> 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, <br/> 13, 13 }; <br/> Private Static final int distance_values [] = {1, 2, 3, 4, 5, 7, 9, 13, 17, <br/> 25, 33, 49, 65, 97,129,193,257,385,513,769,102 5, 1537,204 9, <br/> 3073,409 7, 6145,819 3, 12289,163 85, 24577}; <br/> private St Atic final int dynamic_length_order [] = {16, 17, 18, 0, 8, 7, 9, <br/> 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; </P> <p> private int curindex, curbyte, curbit; </P> <p> Public final byte [] inflate (byte data [], int startidx, int size) {<br/> curindex = startidx; <br/> byte RET [] = new byte [size]; <br/> int idx, bfinal, btype; <br/> idx = bfinal = btype = curbyte = curbit = 0; <br/> do {<br/> bfin Al = readbits (data, 1); <br/> btype = readbits (data, 2); <br/> If (btype = btype_none) {<br/> curbit = 0; <br/> // Len. <br/> int Len = readbits (data, 16); <br/> // nlen. <br/> readbits (data, 16); <br/> system. arraycopy (data, curindex, RET, idx, Len); <br/> curindex + = Len; <br/> idx + = Len; <br/>} else {<br/> int literaltree [], distancetree []; <br/> If (btype = btype_dynamic) {<br/> int hli T = readbits (data, 5) + 257; <br/> int hdist = readbits (data, 5) + 1; <br/> int hclen = readbits (data, 4) + 4; <br/> byte lengthbits [] = new byte [max_code_lengths + 1]; <br/> for (INT I = 0; I <pclen; I ++) <br/> lengthbits [dynamic_length_order [I] = (byte) readbits (data, 3); <br/> int lengthtree [] = huffmantree (lengthbits, max_code_lengths ); <br/> literaltree = huffmantree (codelengths (data, <br/> Lengthtree, hsf-), hsf-- 1); <br/> distancetree = huffmantree (codelengths (data, <br/> lengthtree, hdist), hdist-1 ); <br/>} else {<br/> byte literalbits [] = new byte [max_code_literals + 1]; <br/> for (INT I = 144; -- I> = 0; literalbits [I] = 8); <br/> for (INT I = 256; -- I> = 144; literalbits [I] = 9 ); <br/> for (INT I = 280; -- I >= 256; literalbits [I] = 7); <br/> for (INT I = 288; -- I >=280; Literalbits [I] = 8); <br/> literaltree = huffmantree (literalbits, max_code_literals ); </P> <p> byte distancebits [] = new byte [max_code_distances + 1]; <br/> for (INT I = distancebits. length; -- I> = 0; distancebits [I] = 5); <br/> distancetree = huffmantree (distancebits, max_code_distances ); <br/>}< br/> int code = 0, Leb = 0, Deb = 0; <br/> while (code = readcode (data, literaltree ))! = Eob_code) {<br/> If (code> eob_code) {<br/> code-= 257; <br/> int length = length_values [Code]; <br/> If (LEB = length_extra_bits [Code])> 0) <br/> Length + = readbits (data, LEB ); <br/> code = readcode (data, distancetree); <br/> int distance = distance_values [Code]; <br/> If (DEB = distance_extra_bits [Code])> 0) <br/> distance + = readbits (data, Deb); <br/> int offset = idx-distance; <br/> While (distance <length) {<br/> system. arraycopy (Ret, offset, RET, idx, distance); <br/> idx + = distance; <br/> length-= distance; <br/> distance <= 1; <br/>}< br/> system. arraycopy (Ret, offset, RET, idx, length); <br/> idx + = length; <br/>} else {<br/> RET [idx ++] = (byte) code; <br/>}< br/>}while (bfinal = 0); <br/> return ret; <br/>}</P> <p> private final int readbits (Byte BB [], int N) {<br/> int DATA = (curbit = 0? (Curbyte = (BB [curindex ++] & 0xff) <br/>: (curbyte> curbit )); <br/> for (INT I = (8-curbit); I <n; I + = 8) {<br/> curbyte = (BB [curindex ++] & 0xff); <br/> data |=( curbyte <I ); <br/>}< br/> curbit = (curbit + n) & 7; <br/> return (Data & (1 <n)-1 )); <br/>}</P> <p> private final int readcode (byte BB [], int tree []) {<br/> int node = tree [0]; <br/> while (node> = 0) {<br/> If (curbi T = 0) curbyte = (BB [curindex ++] & 0xff); <br/> node = (curbyte & (1 <curbit )) = 0 )? Tree [node> 16] <br/>: Tree [node & 0 xFFFF]); <br/> curbit = (curbit + 1) & 7; <br/>}< br/> return (node & 0 xFFFF ); <br/>}</P> <p> private final byte [] codelengths (byte BB [], int lentree [], int count) {<br/> byte bits [] = new byte [count]; <br/> for (INT I = 0, code = 0, last = 0; I <count ;) {<br/> code = readcode (BB, lentree); <br/> If (Code >=16) {<br/> int repeat = 0; <br/> If (code = 16) {<Br/> repeat = 3 + readbits (BB, 2); <br/> code = last; <br/>} else {<br/> If (code = 17) <br/> repeat = 3 + readbits (BB, 3 ); <br/> else <br/> repeat = 11 + readbits (BB, 7); <br/> code = 0; <br/>}< br/> while (Repeat --> 0) <br/> bits [I ++] = (byte) code; <br/>}else {<br/> bits [I ++] = (byte) Code; <br/>}< br/> last = code; <br/>}< br/> return bits; <br/>}</P> <p> private final static in T [] huffmantree (byte bits [], int maxcode) {<br/> int bl_count [] = new int [max_bits + 1]; <br/> for (INT I = 0, n = bits. length; I <n; I ++) <br/> bl_count [bits [I] ++; <br/> int code = 0; <br/> bl_count [0] = 0; <br/> int next_code [] = new int [max_bits + 1]; <br/> for (INT I = 1; I <= max_bits; I ++) <br/> next_code [I] = code = (code + bl_count [I-1]) <1; <br/> int tree [] = new int [(maxcode <1) + Max_bits]; <br/> int treeinsert = 1; <br/> for (INT I = 0; I <= maxcode; I ++) {<br/> int Len = bits [I]; <br/> If (Len! = 0) {<br/> code = next_code [Len] ++; <br/> int node = 0; <br/> for (INT bit = len-1; bit> = 0; bit --) {<br/> int value = Code & (1 <bit); <br/> If (value = 0) {<br/> int left = tree [node]> 16; <br/> If (Left = 0) {<br/> tree [node] | = (treeinsert <16); <br/> node = treeinsert ++; <br/>} else <br/> node = left; <br/>} else {<br/> int right = tree [node] & 0 xFFFF; <br/> If (Right = 0) {<Br/> tree [node] | = treeinsert; <br/> node = treeinsert ++; <br/>} else <br/> node = right; <br/>}< br/> tree [node] = 0x80000000 | I; <br/>}< br/> return tree; <br/>}</P> <p> private byte [] data; </P> <p> private hashtable httoc; </P> <p> Public zipme (byte [] data) {<br/> Reset (data ); <br/>}</P> <p> Public zipme (inputstream is) throws ioexception {<br/> byte [] BB = inputstreamtoby TES (is); <br/> Reset (bb); <br/>}</P> <p> Public final zipme reset (byte [] data) {<br/> This. data = data; <br/> httoc = NULL; <br/> return this; <br/>}</P> <p> Public final vector list () {<br/> hashtable TOC; <br/> If (TOC = httoc) = NULL) {<br/> TOC = httoc = new hashtable (); <br/> int offset, I; <br/> offset = I = 0; <br/> for (;) {<br/> int n = read (data, offset, 4); <br/> If (n! = 0x04034b50) break; // end of data section <br/> Offset + = 8; // header, pkware_ver, global_flag <br/> int method = read (data, offset, 2); <br/> Offset + = 10; // method, date, time, CRC <br/> int size = read (data, offset, 4 ); <br/> Offset + = 4; // compressed_size <br/> int orisize = read (data, offset, 4); <br/> Offset + = 4; // original_size <br/> int filenamelen = read (data, offset, 2); <br/> Offset + = 2; <br/> int extlen = read (data, offset, 2); <br/> Offset + = 2; <br/> string filename = new string (data, offset, filenamelen ); <br/> Offset + = filenamelen + extlen; <br/> TOC. put (filename, new int [] {offset, size, orisize, method, I ++}); <br/> Offset + = size; <br/>}< br/> vector ret = new vector (TOC. size (); <br/> for (enumeration E = toc. keys (); E. hasmoreelements ();) {<br/> string filename = (string) E. nextelement (); <br/> ret. add (filename); <br/>}< br/> return ret; <br/>}</P> <p> Public final byte [] Get (string name) {<br/> If (httoc = NULL) List (); <br/> int [] info = (INT []) httoc. get (name); <br/> If (Info = NULL) return NULL; <br/> If (info [1] = 0) return New byte [0]; <br/> If (info [3] = 0) {// store <br/> byte [] ret = new byte [info [2]; <br/> system. arraycopy (data, info [0], RET, 0, info [2]); <br/> return ret; <br/>} else if (info [3] = 8) {// deflate <br/> byte [] ret = inflate (data, info [0], info [2]); <br/> return ret; <br/>}< br/> return NULL; <br/>}</P> <p> Private Static final int read (byte [] data, int offset, int Len) {<br/> int ret = 0; <br/> for (INT I = offset, j = 0, n = offset + Len; I <n; I ++, J + = 8) {<br/> RET | = (data [I] & 0xff) <j); <br/>}< br/> return ret; <br/>}</P> <p> Private Static final byte [] inputstreamtobytes (inputstream is) throws ioexception {<br/> bytearrayoutputstream Bos = new bytearrayoutputstream (); <br/> byte [] BB = new byte [10000]; <br/> for (INT Len = is. read (bb); Len> 0; Len = is. read (bb) {<br/> Bos. write (BB, 0, Len); <br/>}< br/> return Bos. tobytearray (); <br/>}</P> <p >}< br/>