zip压缩(不是解压)在java里的用法,己解决中文问题。

zip压缩(不是解压)在java里的用法,己解决中文问题。
首先上代码,一个是工具类,一个是修该的SUN RUNTIME 里的 ZipOutputStream 类(用来解决中文乱码问题)。

ZipTools.java

package  net.techjava.util;

import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileOutputStream;
import  java.util.ArrayList;
import  java.util.Iterator;
import  java.util.List;

import  net.techjava.zip.ZipEntry;
import  net.techjava.zip.ZipOutputStream;


public   class  ZipTools {

    
/**
     * 生成ZIP文件,把一系列的文件生成到一个ZIP里,使用无目录的形式。
     * 
@param  fileFullPathList 要压缩的文件列表
     * 
@param  outputFullFileName 压缩成的文件的输出路径  
     * 
@author  Beiling Yu 2008年10月27日 14时59分18秒
     * 
@return
     
*/
    
public   static   boolean  MakeZip(List < String >  fileFullPathList,String outputFullFileName){
        
try  {

            
byte [] buf  =   new   byte [ 1024 ];

            ZipOutputStream out 
=   new  ZipOutputStream( new  FileOutputStream(outputFullFileName));

            
for  (Iterator < String >  i  =  fileFullPathList.iterator(); i.hasNext();) {

                String nowFilePath 
=  (String)i.next();

                File nowFile 
=   new  File(nowFilePath);

                FileInputStream in 
=   new  FileInputStream(nowFile);

                
// out.putNextEntry(new ZipEntry(new String(nowFile.getName().getBytes("gb2312"),"ISO8859-1")));
                out.putNextEntry( new  ZipEntry(nowFile.getName()));

                
int  len;
                
while  ((len  =  in.read(buf))  >   0 ) {
                    out.write(buf, 
0 , len);
                }

                out.closeEntry();
                in.close();
            }

            out.close();

        } 
catch  (Exception e) {
            e.printStackTrace();
            
return   false ;
        }
        
return   true ;
    }

    
public   static   void  main(String[] args) {

        List
< String >  flist  =   new  ArrayList < String > ();
        flist.add(
" D:\\中文1.doc " );
        flist.add(
" D:\\中文2.doc " );
        flist.add(
" D:\\中文3.doc " );
        flist.add(
" D:\\tet.doc " );
        flist.add(
" D:\\Tomcat5.doc " );

        System.out.println(MakeZip(flist,
" D:\\temp.zip " ));

        }

}

ZipOutputStream.java

/*
 * 
 *
 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 
*/
package  net.techjava.zip;

import  java.io.IOException;
import  java.io.OutputStream;
import  java.io.UnsupportedEncodingException;
import  java.util.Enumeration;
import  java.util.Hashtable;
import  java.util.Vector;
import  java.util.zip.CRC32;
import  java.util.zip.Deflater;
import  java.util.zip.ZipException;


public
class  ZipOutputStream  extends  DeflaterOutputStream  implements  ZipConstants {
    
private  ZipEntry entry;
    
private  Vector entries  =   new  Vector();
    
private  Hashtable names  =   new  Hashtable();
    
private  CRC32 crc  =   new  CRC32();
    
private   long  written;
    
private   long  locoff  =   0 ;
    
private  String comment;
    
private   int  method  =  DEFLATED;
    
private   boolean  finished;

    
private   boolean  closed  =   false ;

    
/**
     * Check to make sure that this stream has not been closed
     
*/
    
private   void  ensureOpen()  throws  IOException {
        
if  (closed) {
            
throw   new  IOException( " Stream closed " );
        }
    }
    
/**
     * Compression method for uncompressed (STORED) entries.
     
*/
    
public   static   final   int  STORED  =  ZipEntry.STORED;

    
/**
     * Compression method for compressed (DEFLATED) entries.
     
*/
    
public   static   final   int  DEFLATED  =  ZipEntry.DEFLATED;

    
/**
     * Creates a new ZIP output stream.
     * 
@param  out the actual output stream
     
*/
    
public  ZipOutputStream(OutputStream out) {
        
super (out,  new  Deflater(Deflater.DEFAULT_COMPRESSION,  true ));
        usesDefaultDeflater 
=   true ;
    }

    
/**
     * Sets the ZIP file comment.
     * 
@param  comment the comment string
     * 
@exception  IllegalArgumentException if the length of the specified
     *          ZIP file comment is greater than 0xFFFF bytes
     
*/
    
public   void  setComment(String comment) {
        
if  (comment  !=   null   &&  comment.length()  >   0xffff / 3  
                
&&  getUTF8Length(comment)  >   0xffff ) {
            
throw   new  IllegalArgumentException( " ZIP file comment too long. " );
        }
        
this .comment  =  comment;
    }

    
/**
     * Sets the default compression method for subsequent entries. This
     * default will be used whenever the compression method is not specified
     * for an individual ZIP file entry, and is initially set to DEFLATED.
     * 
@param  method the default compression method
     * 
@exception  IllegalArgumentException if the specified compression method
     *          is invalid
     
*/
    
public   void  setMethod( int  method) {
        
if  (method  !=  DEFLATED  &&  method  !=  STORED) {
            
throw   new  IllegalArgumentException( " invalid compression method " );
        }
        
this .method  =  method;
    }

    
/**
     * Sets the compression level for subsequent entries which are DEFLATED.
     * The default setting is DEFAULT_COMPRESSION.
     * 
@param  level the compression level (0-9)
     * 
@exception  IllegalArgumentException if the compression level is invalid
     
*/
    
public   void  setLevel( int  level) {
        def.setLevel(level);
    }

    
/**
     * Begins writing a new ZIP file entry and positions the stream to the
     * start of the entry data. Closes the current entry if still active.
     * The default compression method will be used if no compression method
     * was specified for the entry, and the current time will be used if
     * the entry has no set modification time.
     * 
@param  e the ZIP entry to be written
     * 
@exception  ZipException if a ZIP format error has occurred
     * 
@exception  IOException if an I/O error has occurred
     
*/
    
public   void  putNextEntry(ZipEntry e)  throws  IOException {
        ensureOpen();
        
if  (entry  !=   null ) {
            closeEntry();    
//  close previous entry
        }
        
if  (e.time  ==   - 1 ) {
            e.setTime(System.currentTimeMillis());
        }
        
if  (e.method  ==   - 1 ) {
            e.method 
=  method;     //  use default method
        }
        
switch  (e.method) {
        
case  DEFLATED:
            
if  (e.size  ==   - 1   ||  e.csize  ==   - 1   ||  e.crc  ==   - 1 ) {
                
//  store size, compressed size, and crc-32 in data descriptor
                
//  immediately following the compressed entry data
                e.flag  =   8 ;
            } 
else   if  (e.size  !=   - 1   &&  e.csize  !=   - 1   &&  e.crc  !=   - 1 ) {
                
//  store size, compressed size, and crc-32 in LOC header
                e.flag  =   0 ;
            } 
else  {
                
throw   new  ZipException(
                
" DEFLATED entry missing size, compressed size, or crc-32 " );
            }
            e.version 
=   20 ;
            
break ;
        
case  STORED:
            
//  compressed size, uncompressed size, and crc-32 must all be
            
//  set for entries using STORED compression method
             if  (e.size  ==   - 1 ) {
                e.size 
=  e.csize;
            } 
else   if  (e.csize  ==   - 1 ) {
                e.csize 
=  e.size;
            } 
else   if  (e.size  !=  e.csize) {
                
throw   new  ZipException(
                
" STORED entry where compressed != uncompressed size " );
            }
            
if  (e.size  ==   - 1   ||  e.crc  ==   - 1 ) {
                
throw   new  ZipException(
                
" STORED entry missing size, compressed size, or crc-32 " );
            }
            e.version 
=   10 ;
            e.flag 
=   0 ;
            
break ;
        
default :
            
throw   new  ZipException( " unsupported compression method " );
        }
        e.offset 
=  written;
        
if  (names.put(e.name, e)  !=   null ) {
            
throw   new  ZipException( " duplicate entry:  "   +  e.name);
        }
        writeLOC(e);
        entries.addElement(e);
        entry 
=  e;
    }

    
/**
     * Closes the current ZIP entry and positions the stream for writing
     * the next entry.
     * 
@exception  ZipException if a ZIP format error has occurred
     * 
@exception  IOException if an I/O error has occurred
     
*/
    
public   void  closeEntry()  throws  IOException {
        ensureOpen();
        ZipEntry e 
=  entry;
        
if  (e  !=   null ) {
            
switch  (e.method) {
            
case  DEFLATED:
                def.finish();
                
while  ( ! def.finished()) {
                    deflate();
                }
                
if  ((e.flag  &   8 ==   0 ) {
                    
//  verify size, compressed size, and crc-32 settings
                     if  (e.size  !=  def.getTotalIn()) {
                        
throw   new  ZipException(
                                
" invalid entry size (expected  "   +  e.size  +
                                
"  but got  "   +  def.getTotalIn()  +   "  bytes) " );
                    }
                    
if  (e.csize  !=  def.getTotalOut()) {
                        
throw   new  ZipException(
                                
" invalid entry compressed size (expected  "   +
                                e.csize 
+   "  but got  "   +  def.getTotalOut()  +
                        
"  bytes) " );
                    }
                    
if  (e.crc  !=  crc.getValue()) {
                        
throw   new  ZipException(
                                
" invalid entry CRC-32 (expected 0x "   +
                                Long.toHexString(e.crc) 
+   "  but got 0x "   +
                                Long.toHexString(crc.getValue()) 
+   " ) " );
                    }
                } 
else  {
                    e.size 
=  def.getTotalIn();
                    e.csize 
=  def.getTotalOut();
                    e.crc 
=  crc.getValue();
                    writeEXT(e);
                }
                def.reset();
                written 
+=  e.csize;
                
break ;
            
case  STORED:
                
//  we already know that both e.size and e.csize are the same
                 if  (e.size  !=  written  -  locoff) {
                    
throw   new  ZipException(
                            
" invalid entry size (expected  "   +  e.size  +
                            
"  but got  "   +  (written  -  locoff)  +   "  bytes) " );
                }
                
if  (e.crc  !=  crc.getValue()) {
                    
throw   new  ZipException(
                            
" invalid entry crc-32 (expected 0x "   +
                            Long.toHexString(e.crc) 
+   "  but got 0x "   +
                            Long.toHexString(crc.getValue()) 
+   " ) " );
                }
                
break ;
            
default :
                
throw   new  InternalError( " invalid compression method " );
            }
            crc.reset();
            entry 
=   null ;
        }
    }

    
/**
     * Writes an array of bytes to the current ZIP entry data. This method
     * will block until all the bytes are written.
     * 
@param  b the data to be written
     * 
@param  off the start offset in the data
     * 
@param  len the number of bytes that are written
     * 
@exception  ZipException if a ZIP file error has occurred
     * 
@exception  IOException if an I/O error has occurred
     
*/
    
public   synchronized   void  write( byte [] b,  int  off,  int  len)
    
throws  IOException
    {
        ensureOpen();
        
if  (off  <   0   ||  len  <   0   ||  off  >  b.length  -  len) {
            
throw   new  IndexOutOfBoundsException();
        } 
else   if  (len  ==   0 ) {
            
return ;
        }

        
if  (entry  ==   null ) {
            
throw   new  ZipException( " no current ZIP entry " );
        }
        
switch  (entry.method) {
        
case  DEFLATED:
            
super .write(b, off, len);
            
break ;
        
case  STORED:
            written 
+=  len;
            
if  (written  -  locoff  >  entry.size) {
                
throw   new  ZipException(
                
" attempt to write past end of STORED entry " );
            }
            out.write(b, off, len);
            
break ;
        
default :
            
throw   new  InternalError( " invalid compression method " );
        }
        crc.update(b, off, len);
    }

    
/**
     * Finishes writing the contents of the ZIP output stream without closing
     * the underlying stream. Use this method when applying multiple filters
     * in succession to the same output stream.
     * 
@exception  ZipException if a ZIP file error has occurred
     * 
@exception  IOException if an I/O exception has occurred
     
*/
    
public   void  finish()  throws  IOException {
        ensureOpen();
        
if  (finished) {
            
return ;
        }
        
if  (entry  !=   null ) {
            closeEntry();
        }
        
if  (entries.size()  <   1 ) {
            
throw   new  ZipException( " ZIP file must have at least one entry " );
        }
        
//  write central directory
         long  off  =  written;
        Enumeration e 
=  entries.elements();
        
while  (e.hasMoreElements()) {
            writeCEN((ZipEntry)e.nextElement());
        }
        writeEND(off, written 
-  off);
        finished 
=   true ;
    }

    
/**
     * Closes the ZIP output stream as well as the stream being filtered.
     * 
@exception  ZipException if a ZIP file error has occurred
     * 
@exception  IOException if an I/O error has occurred
     
*/
    
public   void  close()  throws  IOException {
        
if  ( ! closed) {
            
super .close();
            closed 
=   true ;
        }
    }

    
/*
     * Writes local file (LOC) header for specified entry.
     
*/
    
private   void  writeLOC(ZipEntry e)  throws  IOException {
        writeInt(LOCSIG);        
//  LOC header signature
        writeShort(e.version);       //  version needed to extract
        writeShort(e.flag);          //  general purpose bit flag
        writeShort(e.method);        //  compression method
        writeInt(e.time);            //  last modification time
         if  ((e.flag  &   8 ==   8 ) {
            
//  store size, uncompressed size, and crc-32 in data descriptor
            
//  immediately following compressed entry data
            writeInt( 0 );
            writeInt(
0 );
            writeInt(
0 );
        } 
else  {
            writeInt(e.crc);        
//  crc-32
            writeInt(e.csize);       //  compressed size
            writeInt(e.size);        //  uncompressed size
        }
        
byte [] nameBytes  =  getUTF8Bytes(e.name);
        writeShort(nameBytes.length);
        writeShort(e.extra 
!=   null   ?  e.extra.length :  0 );
        writeBytes(nameBytes, 
0 , nameBytes.length);
        
if  (e.extra  !=   null ) {
            writeBytes(e.extra, 
0 , e.extra.length);
        }
        locoff 
=  written;
    }

    
/*
     * Writes extra data descriptor (EXT) for specified entry.
     
*/
    
private   void  writeEXT(ZipEntry e)  throws  IOException {
        writeInt(EXTSIG);        
//  EXT header signature
        writeInt(e.crc);         //  crc-32
        writeInt(e.csize);         //  compressed size
        writeInt(e.size);         //  uncompressed size
    }

    
/*
     * Write central directory (CEN) header for specified entry.
     * REMIND: add support for file attributes
     
*/
    
private   void  writeCEN(ZipEntry e)  throws  IOException {
        writeInt(CENSIG);        
//  CEN header signature
        writeShort(e.version);         //  version made by
        writeShort(e.version);         //  version needed to extract
        writeShort(e.flag);         //  general purpose bit flag
        writeShort(e.method);         //  compression method
        writeInt(e.time);         //  last modification time
        writeInt(e.crc);         //  crc-32
        writeInt(e.csize);         //  compressed size
        writeInt(e.size);         //  uncompressed size
         byte [] nameBytes  =  getUTF8Bytes(e.name);
        writeShort(nameBytes.length);
        writeShort(e.extra 
!=   null   ?  e.extra.length :  0 );
        
byte [] commentBytes;
        
if  (e.comment  !=   null ) {
            commentBytes 
=  getUTF8Bytes(e.comment);
            writeShort(commentBytes.length);
        } 
else  {
            commentBytes 
=   null ;
            writeShort(
0 );
        }
        writeShort(
0 );             //  starting disk number
        writeShort( 0 );             //  internal file attributes (unused)
        writeInt( 0 );             //  external file attributes (unused)
        writeInt(e.offset);         //  relative offset of local header
        writeBytes(nameBytes,  0 , nameBytes.length);
        
if  (e.extra  !=   null ) {
            writeBytes(e.extra, 
0 , e.extra.length);
        }
        
if  (commentBytes  !=   null ) {
            writeBytes(commentBytes, 
0 , commentBytes.length);
        }
    }

    
/*
     * Writes end of central directory (END) header.
     
*/
    
private   void  writeEND( long  off,  long  len)  throws  IOException {
        writeInt(ENDSIG);        
//  END record signature
        writeShort( 0 );             //  number of this disk
        writeShort( 0 );             //  central directory start disk
        writeShort(entries.size());  //  number of directory entries on disk
        writeShort(entries.size());  //  total number of directory entries
        writeInt(len);             //  length of central directory
        writeInt(off);             //  offset of central directory
         if  (comment  !=   null ) {         //  zip file comment
             byte [] b  =  getUTF8Bytes(comment);
            writeShort(b.length);
            writeBytes(b, 
0 , b.length);
        } 
else  {
            writeShort(
0 );
        }
    }

    
/*
     * Writes a 16-bit short to the output stream in little-endian byte order.
     
*/
    
private   void  writeShort( int  v)  throws  IOException {
        OutputStream out 
=   this .out;
        out.write((v 
>>>   0 &   0xff );
        out.write((v 
>>>   8 &   0xff );
        written 
+=   2 ;
    }

    
/*
     * Writes a 32-bit int to the output stream in little-endian byte order.
     
*/
    
private   void  writeInt( long  v)  throws  IOException {
        OutputStream out 
=   this .out;
        out.write((
int )((v  >>>    0 &   0xff ));
        out.write((
int )((v  >>>    8 &   0xff ));
        out.write((
int )((v  >>>   16 &   0xff ));
        out.write((
int )((v  >>>   24 &   0xff ));
        written 
+=   4 ;
    }

    
/*
     * Writes an array of bytes to the output stream.
     
*/
    
private   void  writeBytes( byte [] b,  int  off,  int  len)  throws  IOException {
        
super .out.write(b, off, len);
        written 
+=  len;
    }

    
/*
     * Returns the length of String's UTF8 encoding.
     
*/
    
static   int  getUTF8Length(String s) {
        
int  count  =   0 ;
        
for  ( int  i  =   0 ; i  <  s.length(); i ++ ) {
            
char  ch  =  s.charAt(i); 
            
if  (ch  <=   0x7f ) {
                count
++ ;
            } 
else   if  (ch  <=   0x7ff ) {
                count 
+=   2 ;
            } 
else  {
                count 
+=   3 ;
            }
        }
        
return  count;
    }

    
/*
     * Returns an array of bytes representing the UTF8 encoding
     * of the specified String.
     
*/
    
private   static   byte [] getUTF8Bytes(String s) {
//         char[] c = s.toCharArray();
//         int len = c.length;
//          //  Count the number of encoded bytes
//         int count = 0;
//         for (int i = 0; i < len; i++) {
//             int ch = c[i];
//             if (ch <= 0x7f) {
//                 count++;
//             } else if (ch <= 0x7ff) {
//                 count += 2;
//             } else {
//                 count += 3;
//             }
//         }
//          //  Now return the encoded bytes
//         byte[] b = new byte[count];
//         int off = 0;
//         for (int i = 0; i < len; i++) {
//             int ch = c[i];
//             if (ch <= 0x7f) {
//                 b[off++] = (byte)ch;
//             } else if (ch <= 0x7ff) {
//                 b[off++] = (byte)((ch >> 6) | 0xc0);
//                 b[off++] = (byte)((ch & 0x3f) | 0x80);
//             } else {
//                 b[off++] = (byte)((ch >> 12) | 0xe0);
//                 b[off++] = (byte)(((ch >> 6) & 0x3f) | 0x80);
//                 b[off++] = (byte)((ch & 0x3f) | 0x80);
//             }
//         }
//         return b;
         try  {
            
return  s.getBytes( " gbk " );
        } 
catch  (UnsupportedEncodingException e) {
            
return  getUTF8Bytes(s);
        }
    }
}

时间关系,大家自己看啊,其实就是改了最后一个函数(   private  static  byte [] getUTF8Bytes(String s)  )。

你可能感兴趣的:(zip压缩(不是解压)在java里的用法,己解决中文问题。)