java压缩文件,中文问题
生活随笔
收集整理的這篇文章主要介紹了
java压缩文件,中文问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
今天有同學問起來用java做壓縮和解壓縮的程序時,出現中文問題,我以前做過,不過已經很久了,那里又沒有寫日志,所以也忘記了自己所做的壓縮小程序,今天又重新寫一編,真是很浪費時間,平時要多做筆記,以后用到時就可以順手拿來,不然跟白學一樣,一切從頭再來,切記切記。
??? 這里是用java.util.zip.ZipOutputStream來做壓縮的話會出現將中文名字的文件一縮后,在壓縮包里就會出現亂碼的文件名,解決的辦法可以修改java.util.zip.ZipOutputStream這個類,加入編碼方式就可以,具體如下:
my.java.util.zip.ZipOutputStream
Java代碼 ?/*? ?*?? ?*? ?*?Copyright?2003?Sun?Microsystems,?Inc.?All?rights?reserved.? ?*?SUN?PROPRIETARY/CONFIDENTIAL.?Use?is?subject?to?license?terms.? ?*/?? package?my.java.util.zip;?? ?? import?java.io.IOException;?? import?java.io.OutputStream;?? 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?String?encoding?=?"UTF-8";?//?為了支持中文,添加?? ?? ????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;?? ????}?? ?? ????/**? ?????*?Creates?a?new?ZIP?output?stream.? ?????*?? ?????*?@param?out? ?????*????????????the?actual?output?stream? ?????*?@param?encoding? ?????*????????????set?stream's?code?為了支持中文添加? ?????*/?? ????public?ZipOutputStream(OutputStream?out,?String?encoding)?{?? ????????super(out,?new?Deflater(Deflater.DEFAULT_COMPRESSION,?true));?? ????????usesDefaultDeflater?=?true;?? ????????this.encoding?=?encoding;?? ????}?? ?? ????/**? ?????*?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();//?defate意思:漏氣;?(使)…癟下去?? ????????????????}?? ????????????????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);?? ????????//?為了支持中文,添加?begin?? ????????byte[]?nameBytes?=?null;?? ????????try?{?? ????????????if?(this.encoding.toUpperCase().equals("UTF-8"))?? ????????????????nameBytes?=?getUTF8Bytes(e.name);?? ????????????else?? ????????????????nameBytes?=?e.name.getBytes(this.encoding);?? ????????}?catch?(Exception?byteE)?{?? ????????????nameBytes?=?getUTF8Bytes(e.name);?? ????????}?? ????????//?為了支持中文,添加?end?? ????????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);?? ????????//?為了支持中文,添加?begin?? ????????byte[]?nameBytes?=?null;?? ????????try?{?? ????????????if?(this.encoding.toUpperCase().equals("UTF-8"))?? ????????????????nameBytes?=?getUTF8Bytes(e.name);?? ????????????else?? ????????????????nameBytes?=?e.name.getBytes(this.encoding);?? ????????}?catch?(Exception?byteE)?{?? ????????????nameBytes?=?getUTF8Bytes(e.name);?? ????????}?? ????????//?為了支持中文,添加?end?? ????????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;?? ????}?? }??
同時也要修改java.util.zip.ZipEntry這個類,主要是增加了三個屬性:
int flag;
int version;
long offset;
在修改的ZipOutputStream類里會用到,具體ZipEntry代碼如下:
my.java.util.zip.ZipEntry
Java代碼 ?/*? ?*?? ?*? ?*?Copyright?2003?Sun?Microsystems,?Inc.?All?rights?reserved.? ?*?SUN?PROPRIETARY/CONFIDENTIAL.?Use?is?subject?to?license?terms.? ?*/?? package?my.java.util.zip;?? ?? import?java.util.Date;?? ?? public?class?ZipEntry?implements?ZipConstants,?Cloneable?{?? ????String?name;?//?entry?name?? ????long?time?=?-1;?//?modification?time?(in?DOS?time)?? ????long?crc?=?-1;?//?crc-32?of?entry?data?? ????long?size?=?-1;?//?uncompressed?size?of?entry?data?? ????long?csize?=?-1;?//?compressed?size?of?entry?data?? ????int?method?=?-1;?//?compression?method?? ????byte[]?extra;?//?optional?extra?field?data?for?entry?? ????String?comment;?//?optional?comment?string?for?entry?? ????//?The?following?flags?are?used?only?by?Zip{Input,Output}Stream?? ????int?flag;?//?bit?flags?? ????int?version;?//?version?needed?to?extract?? ????long?offset;?//?offset?of?loc?header?? ?? ????/**? ?????*?Compression?method?for?uncompressed?entries.? ?????*/?? ????public?static?final?int?STORED?=?0;?? ?? ????/**? ?????*?Compression?method?for?compressed?(deflated)?entries.? ?????*/?? ????public?static?final?int?DEFLATED?=?8;?? ?? ????//?static?{?? ????//?/*?load?the?zip?library?*/?? ????//?java.security.AccessController.doPrivileged(?? ????//?new?sun.security.action.LoadLibraryAction("zip"));?? ????//?//initIDs();?? ????//?}?? ?? ????private?static?native?void?initIDs();?? ?? ????/**? ?????*?Creates?a?new?zip?entry?with?the?specified?name.? ?????*?? ?????*?@param?name? ?????*????????????the?entry?name? ?????*?@exception?NullPointerException? ?????*????????????????if?the?entry?name?is?null? ?????*?@exception?IllegalArgumentException? ?????*????????????????if?the?entry?name?is?longer?than?0xFFFF?bytes? ?????*/?? ????public?ZipEntry(String?name)?{?? ????????if?(name?==?null)?{?? ????????????throw?new?NullPointerException();?? ????????}?? ????????if?(name.length()?>?0xFFFF)?{?? ????????????throw?new?IllegalArgumentException("entry?name?too?long");?? ????????}?? ????????this.name?=?name;?? ????}?? ?? ????/**? ?????*?Creates?a?new?zip?entry?with?fields?taken?from?the?specified?zip?entry.? ?????*?? ?????*?@param?e? ?????*????????????a?zip?Entry?object? ?????*/?? ?? ????/**? ?????*?Returns?the?name?of?the?entry.? ?????*?? ?????*?@return?the?name?of?the?entry? ?????*/?? ????public?String?getName()?{?? ????????return?name;?? ????}?? ?? ????/**? ?????*?Sets?the?modification?time?of?the?entry.? ?????*?? ?????*?@param?time? ?????*????????????the?entry?modification?time?in?number?of?milliseconds?since? ?????*????????????the?epoch? ?????*?@see?#getTime()? ?????*/?? ????public?void?setTime(long?time)?{?? ????????this.time?=?javaToDosTime(time);?? ????}?? ?? ????/**? ?????*?Returns?the?modification?time?of?the?entry,?or?-1?if?not?specified.? ?????*?? ?????*?@return?the?modification?time?of?the?entry,?or?-1?if?not?specified? ?????*?@see?#setTime(long)? ?????*/?? ????public?long?getTime()?{?? ????????return?time?!=?-1???dosToJavaTime(time)?:?-1;?? ????}?? ?? ????/**? ?????*?Sets?the?uncompressed?size?of?the?entry?data.? ?????*?? ?????*?@param?size? ?????*????????????the?uncompressed?size?in?bytes? ?????*?@exception?IllegalArgumentException? ?????*????????????????if?the?specified?size?is?less?than?0?or?greater?than? ?????*????????????????0xFFFFFFFF?bytes? ?????*?@see?#getSize()? ?????*/?? ????public?void?setSize(long?size)?{?? ????????if?(size?<?0?||?size?>?0xFFFFFFFFL)?{?? ????????????throw?new?IllegalArgumentException("invalid?entry?size");?? ????????}?? ????????this.size?=?size;?? ????}?? ?? ????/**? ?????*?Returns?the?uncompressed?size?of?the?entry?data,?or?-1?if?not?known.? ?????*?? ?????*?@return?the?uncompressed?size?of?the?entry?data,?or?-1?if?not?known? ?????*?@see?#setSize(long)? ?????*/?? ????public?long?getSize()?{?? ????????return?size;?? ????}?? ?? ????/**? ?????*?Returns?the?size?of?the?compressed?entry?data,?or?-1?if?not?known.?In?the? ?????*?case?of?a?stored?entry,?the?compressed?size?will?be?the?same?as?the? ?????*?uncompressed?size?of?the?entry.? ?????*?? ?????*?@return?the?size?of?the?compressed?entry?data,?or?-1?if?not?known? ?????*?@see?#setCompressedSize(long)? ?????*/?? ????public?long?getCompressedSize()?{?? ????????return?csize;?? ????}?? ?? ????/**? ?????*?Sets?the?size?of?the?compressed?entry?data.? ?????*?? ?????*?@param?csize? ?????*????????????the?compressed?size?to?set?to? ?????*?@see?#getCompressedSize()? ?????*/?? ????public?void?setCompressedSize(long?csize)?{?? ????????this.csize?=?csize;?? ????}?? ?? ????/**? ?????*?Sets?the?CRC-32?checksum?of?the?uncompressed?entry?data.? ?????*?? ?????*?@param?crc? ?????*????????????the?CRC-32?value? ?????*?@exception?IllegalArgumentException? ?????*????????????????if?the?specified?CRC-32?value?is?less?than?0?or?greater? ?????*????????????????than?0xFFFFFFFF? ?????*?@see?#setCrc(long)? ?????*/?? ????public?void?setCrc(long?crc)?{?? ????????if?(crc?<?0?||?crc?>?0xFFFFFFFFL)?{?? ????????????throw?new?IllegalArgumentException("invalid?entry?crc-32");?? ????????}?? ????????this.crc?=?crc;?? ????}?? ?? ????/**? ?????*?Returns?the?CRC-32?checksum?of?the?uncompressed?entry?data,?or?-1?if?not? ?????*?known.? ?????*?? ?????*?@return?the?CRC-32?checksum?of?the?uncompressed?entry?data,?or?-1?if?not? ?????*?????????known? ?????*?@see?#getCrc()? ?????*/?? ????public?long?getCrc()?{?? ????????return?crc;?? ????}?? ?? ????/**? ?????*?Sets?the?compression?method?for?the?entry.? ?????*?? ?????*?@param?method? ?????*????????????the?compression?method,?either?STORED?or?DEFLATED? ?????*?@exception?IllegalArgumentException? ?????*????????????????if?the?specified?compression?method?is?invalid? ?????*?@see?#getMethod()? ?????*/?? ????public?void?setMethod(int?method)?{?? ????????if?(method?!=?STORED?&&?method?!=?DEFLATED)?{?? ????????????throw?new?IllegalArgumentException("invalid?compression?method");?? ????????}?? ????????this.method?=?method;?? ????}?? ?? ????/**? ?????*?Returns?the?compression?method?of?the?entry,?or?-1?if?not?specified.? ?????*?? ?????*?@return?the?compression?method?of?the?entry,?or?-1?if?not?specified? ?????*?@see?#setMethod(int)? ?????*/?? ????public?int?getMethod()?{?? ????????return?method;?? ????}?? ?? ????/**? ?????*?Sets?the?optional?extra?field?data?for?the?entry.? ?????*?? ?????*?@param?extra? ?????*????????????the?extra?field?data?bytes? ?????*?@exception?IllegalArgumentException? ?????*????????????????if?the?length?of?the?specified?extra?field?data?is?greater? ?????*????????????????than?0xFFFF?bytes? ?????*?@see?#getExtra()? ?????*/?? ????public?void?setExtra(byte[]?extra)?{?? ????????if?(extra?!=?null?&&?extra.length?>?0xFFFF)?{?? ????????????throw?new?IllegalArgumentException("invalid?extra?field?length");?? ????????}?? ????????this.extra?=?extra;?? ????}?? ?? ????/**? ?????*?Returns?the?extra?field?data?for?the?entry,?or?null?if?none.? ?????*?? ?????*?@return?the?extra?field?data?for?the?entry,?or?null?if?none? ?????*?@see?#setExtra(byte[])? ?????*/?? ????public?byte[]?getExtra()?{?? ????????return?extra;?? ????}?? ?? ????/**? ?????*?Sets?the?optional?comment?string?for?the?entry.? ?????*?? ?????*?@param?comment? ?????*????????????the?comment?string? ?????*?@exception?IllegalArgumentException? ?????*????????????????if?the?length?of?the?specified?comment?string?is?greater? ?????*????????????????than?0xFFFF?bytes? ?????*?@see?#getComment()? ?????*/?? ????public?void?setComment(String?comment)?{?? ????????if?(comment?!=?null?&&?comment.length()?>?0xffff?/?3?? ????????????????&&?ZipOutputStream.getUTF8Length(comment)?>?0xffff)?{?? ????????????throw?new?IllegalArgumentException("invalid?entry?comment?length");?? ????????}?? ????????this.comment?=?comment;?? ????}?? ?? ????/**? ?????*?Returns?the?comment?string?for?the?entry,?or?null?if?none.? ?????*?? ?????*?@return?the?comment?string?for?the?entry,?or?null?if?none? ?????*?@see?#setComment(String)? ?????*/?? ????public?String?getComment()?{?? ????????return?comment;?? ????}?? ?? ????/**? ?????*?Returns?true?if?this?is?a?directory?entry.?A?directory?entry?is?defined? ?????*?to?be?one?whose?name?ends?with?a?'/'.? ?????*?? ?????*?@return?true?if?this?is?a?directory?entry? ?????*/?? ????public?boolean?isDirectory()?{?? ????????return?name.endsWith("/");?? ????}?? ?? ????/**? ?????*?Returns?a?string?representation?of?the?ZIP?entry.? ?????*/?? ????public?String?toString()?{?? ????????return?getName();?? ????}?? ?? ????/*? ?????*?Converts?DOS?time?to?Java?time?(number?of?milliseconds?since?epoch).? ?????*/?? ????private?static?long?dosToJavaTime(long?dtime)?{?? ????????Date?d?=?new?Date((int)?(((dtime?>>?25)?&?0x7f)?+?80),?? ????????????????(int)?(((dtime?>>?21)?&?0x0f)?-?1),?? ????????????????(int)?((dtime?>>?16)?&?0x1f),?(int)?((dtime?>>?11)?&?0x1f),?? ????????????????(int)?((dtime?>>?5)?&?0x3f),?(int)?((dtime?<<?1)?&?0x3e));?? ????????return?d.getTime();?? ????}?? ?? ????/*? ?????*?Converts?Java?time?to?DOS?time.? ?????*/?? ????private?static?long?javaToDosTime(long?time)?{?? ????????Date?d?=?new?Date(time);?? ????????int?year?=?d.getYear()?+?1900;?? ????????if?(year?<?1980)?{?? ????????????return?(1?<<?21)?|?(1?<<?16);?? ????????}?? ????????return?(year?-?1980)?<<?25?|?(d.getMonth()?+?1)?<<?21?? ????????????????|?d.getDate()?<<?16?|?d.getHours()?<<?11?|?d.getMinutes()?<<?5?? ????????????????|?d.getSeconds()?>>?1;?? ????}?? ?? ????/**? ?????*?Returns?the?hash?code?value?for?this?entry.? ?????*/?? ????public?int?hashCode()?{?? ????????return?name.hashCode();?? ????}?? ?? ????/**? ?????*?Returns?a?copy?of?this?entry.? ?????*/?? ????public?Object?clone()?{?? ????????try?{?? ????????????ZipEntry?e?=?(ZipEntry)?super.clone();?? ????????????e.extra?=?(extra?==?null???null?:?(byte[])?extra.clone());?? ????????????return?e;?? ????????}?catch?(CloneNotSupportedException?e)?{?? ????????????//?This?should?never?happen,?since?we?are?Cloneable?? ????????????throw?new?InternalError();?? ????????}?? ????}?? }??
有了上面那兩個類后,我們就不用java.util.zip包下的這兩個類來做壓縮,而是用來面的修改后的類來做,我寫了一個簡單的測試程序如下:
Java代碼 ?package?test;?? ?? import?java.io.File;?? import?java.io.FileInputStream;?? import?java.io.FileNotFoundException;?? import?java.io.FileOutputStream;?? import?java.io.IOException;?? ?? import?my.java.util.zip.ZipEntry;?? import?my.java.util.zip.ZipOutputStream;?? ?? public?class?zip?{?? ????private?ZipOutputStream?zipOutputStream;?? ????private?FileOutputStream?fos?=?null;?? ?????? ????public?zip(File?in?,?File?out)?? ????{?? ????????try?{?? ????????????fos?=?new?FileOutputStream(out);?? ????????}?catch?(FileNotFoundException?e)?{?? ????????????e.printStackTrace();?? ????????}?? ????????zipOutputStream?=?new?ZipOutputStream(fos,"GBK");//只能是GBK,用UTF-8不行?? ?????????? ????????doZip(in,?zipOutputStream,?null);?? ?????????? ????????closeZipOutputStream();?? ????}?? ?????? ????/**? ?????*?用遞歸調用的方式將一個文件夾下的所有文件壓縮進壓縮包里? ?????*?@param??input?輸入要壓縮的文件的路徑? ?????*?@param?zos?壓縮輸出流? ?????*?@param?relativePath?文件或文件夾在壓縮包里的相對路徑,一開始應將相對路徑設置為null? ?????*/?? ????public?void?doZip(File?input?,?ZipOutputStream?zos?,?String?relativePath)?? ????{?? ????????FileInputStream?fis;?? ????????byte[]?b?=?new?byte[1024];?? ?????????? ????????try?{?? ?????????????? ????????????if(input.isDirectory())?? ????????????{?? ????????????????relativePath?=?relativePath?==?null???input.getName()?:?relativePath??+?"/"?+?input.getName();?? ?????????????? ????????????????zos.putNextEntry(new?ZipEntry(relativePath?+?"/"));//ZipEntry應該是用來設置壓縮文件所存放的相對路徑的,當是文件夾時一定要后面加上"/",是文件則不用加?? ?????????????????? ????????????????File[]?fileList?=?input.listFiles();?? ????????????????for(int?i?=?0?;?i?<?fileList.length?;?i++)?? ????????????????{?? ????????????????????if(fileList[i].isDirectory())?? ????????????????????{?? ????????????????????????doZip(fileList[i]?,?zos?,?relativePath);?? ????????????????????}?? ????????????????????else??? ????????????????????{????? ????????????????????????zos.putNextEntry(new?ZipEntry(relativePath?+?"/"?+??fileList[i].getName()));//這個一定不要忘記了,不然文件是壓縮不進入的哦?? ????????????????????????fis?=?new?FileInputStream(fileList[i]);?? ????????????????????????while(fis.read(b)?!=?-1)?? ????????????????????????{?? ????????????????????????????zos.write(b);?? ????????????????????????}?? ????????????????????????fis.close();?? ????????????????????}?? ????????????????}?? ????????????}?? ????????????else?{?? ?????????????????? ????????????????relativePath?=?relativePath?==?null???input.getName()?:?relativePath?+?"/"?+??input.getName();?? ?????????????? ????????????????zos.putNextEntry(new?ZipEntry(relativePath));//文件不用加上"/"?? ?????????????????? ????????????????fis?=?new?FileInputStream(input);?? ????????????????while(fis.read(b)?!=?-1)?? ????????????????{?? ????????????????????zos.write(b);?? ????????????????}?? ????????????????fis.close();?? ????????????}?? ?? ????????}?catch?(FileNotFoundException?e)?{?? ????????????e.printStackTrace();?? ????????}catch?(IOException?e)?{?? ????????????e.printStackTrace();?? ????????}?? ????}?? ?????? ????//關閉輸出流?? ????public?void?closeZipOutputStream()?? ????{?? ????????try?{?? ????????????zipOutputStream.close();?? ????????}?catch?(IOException?e)?{?? ????????????e.printStackTrace();?? ????????}?? ????}?? ?????? ????//簡單測試?? ????public?static?void?main(String[]?args)?? ????{?? ????????zip?test?=?new?zip(new?File("F:\\MQ")?,?new?File("F:/MQ.zip"));?? ?????????? ????????System.out.println("壓縮完成");?? ????}?? ?? }??
解壓程序我也寫了,如下:
Java代碼 ?package?test;?? ?? import?java.io.File;?? import?java.io.FileInputStream;?? import?java.io.FileNotFoundException;?? import?java.io.FileOutputStream;?? import?java.io.IOException;?? import?java.util.zip.ZipException;?? import?java.util.zip.ZipFile;?? ?? import?my.java.util.zip.ZipEntry;?? import?my.java.util.zip.ZipInputStream;?? ?? //解壓簡單例子?? public?class?unZip?{?? ?? ????File?in;?? ????File?out;?? ????private?ZipInputStream?zis;?? ?????? ????public?unZip(File?in?,?File?out)?? ????{?? ????????this.in?=?in;?? ????????this.out?=?out;?? ????????initial();?? ????}?? ?????? ????public?void?initial()?? ????{?? ????????//下面是用來檢查輸入的文件是否是zip文件類型用的,若輸入的是.rar類型也會報異常?? ????????try?{?? ????????????ZipFile?zipFile?=?new?ZipFile(in);?? ????????????zipFile.close();?? ????????}?catch?(ZipException?e1)?{?? ????????????e1.printStackTrace();?? ????????????return?;?? ????????}?catch?(IOException?e1)?{?? ????????????e1.printStackTrace();?? ????????????return?;?? ????????}?? ?????????? ????????if(out?==?null?||?!out.isDirectory())?? ????????{?? ????????????System.out.println("請選擇正確的解壓存放的目錄!");?? ????????????return?;?? ????????}?? ?????????? ????????try?{?? ????????????zis?=?new?ZipInputStream(new?FileInputStream(in),"GBK");//支持中文的地方?? ????????????doUnZip();?? ????????}?catch?(FileNotFoundException?e)?{?? ????????????e.printStackTrace();?? ????????????return?;?? ????????}?? ????}?? ?????? ????public?void?doUnZip()?? ????{?? ????????String?pathName;?? ????????ZipEntry?zipEntry;?? ????????File?output;?? ????????FileOutputStream?fos;?? ????????byte[]?b;?? ????????int?len;?? ????????String?desPath;//存放的目標路徑?? ????????String?tempPath;?? ?????????? ????????desPath?=?out.getAbsolutePath();?? ?????????? ????????try?{?? ????????????zipEntry?=?zis.getNextEntry();//用它可以遍歷在壓縮包里的所有條目(包括文件和文件夾都會識別出來)?? ????????????while(zipEntry?!=?null)?? ????????????{?? ????????????????System.out.println(zipEntry.getName());?? ?????????????????? ????????????????tempPath?=?zipEntry.getName();?? ?????????????????? ????????????????//這里的文件路徑用"\\"和"/"混合也是可以正確的創(chuàng)建目錄或訪問目錄等,還是比較方便的?? ????????????????if(desPath.endsWith("\\")?||?desPath.endsWith("/"))?? ????????????????????tempPath?=?desPath?+?tempPath;?? ????????????????else??? ????????????????????tempPath?=?desPath?+?File.separator?+?tempPath;?? ?????????????? ????????????????output?=?new?File(tempPath);?? ?????????????????? ????????????????if(zipEntry.isDirectory())//這里注意啦,不是output.isDirectory()來判斷,是用ZipEntry來判斷?? ????????????????{?? ????????????????????/*? ?????????????????????*?File類的mkdir()和mkdirs()區(qū)別? ?????????????????????*?簡單來說,mkdir()就是創(chuàng)建一個目錄,但前提是要創(chuàng)建的目錄的父目錄一定要存在。?例如:要創(chuàng)建D:\myeclipseprg7\CompilerTest\WebRoot\works?這個目錄,那么D:\myeclipseprg7\CompilerTest\WebRoot\這個目錄就一定要存在,否則用mkdir()無法成功創(chuàng)建目錄。如果父目錄不存在,我們可以用mkdirs(),這樣不管父目錄是否存在,都能創(chuàng)建成功。這樣看來,似乎mkdir()這個函數沒多大用處,今后建議大家只使用mkdirs()。? ?????????????????????*/?? ????????????????????output.mkdirs();?? ????????????????}?? ????????????????else//對于文件就直接輸出??? ????????????????{?? ????????????????????fos?=?new?FileOutputStream(output);?? ????????????????????b?=?new?byte[1024];?? ?????????????????????? ????????????????????while(?(len?=?zis.read(b))?!=?-1)?? ????????????????????{?? ????????????????????????fos.write(b,?0,?len);?? ????????????????????}?? ????????????????????fos.close();?? ????????????????}?? ?????????????????? ????????????????zipEntry?=?zis.getNextEntry();//下一條條目?? ????????????}?? ?????????????? ????????}?catch?(IOException?e)?{?? ????????????e.printStackTrace();?? ????????????return;?? ????????}?? ?????????? ????????closeZipInputStream();?? ????}?? ?????? ????public?void?closeZipInputStream()?? ????{?? ????????try?{?? ????????????zis.close();?? ????????}?catch?(IOException?e)?{?? ????????????e.printStackTrace();?? ????????????return?;?? ????????}?? ????}?? ?????? ????public?static?void?main(String[]?args)?? ????{?? ????????unZip?test?=?new?unZip(new?File("F:\\chenwenbiao.zip"),?new?File("F:\\"));?? ????}?? ?????? }??
我以為用修改后的my.java.util.zip.ZipOutputStream或my.java.util.zip.ZipInputStream就可以解決問題,我將這兩個類拷給同學,在他那里會出錯,原來這兩個類修改也包括了對它們引用到的類的修改,我現將它們打包發(fā)上來,導入就可以用了,中文名的壓縮和解壓縮的問題也可以解決了。
??? 這里是用java.util.zip.ZipOutputStream來做壓縮的話會出現將中文名字的文件一縮后,在壓縮包里就會出現亂碼的文件名,解決的辦法可以修改java.util.zip.ZipOutputStream這個類,加入編碼方式就可以,具體如下:
my.java.util.zip.ZipOutputStream
Java代碼 ?
同時也要修改java.util.zip.ZipEntry這個類,主要是增加了三個屬性:
int flag;
int version;
long offset;
在修改的ZipOutputStream類里會用到,具體ZipEntry代碼如下:
my.java.util.zip.ZipEntry
Java代碼 ?
有了上面那兩個類后,我們就不用java.util.zip包下的這兩個類來做壓縮,而是用來面的修改后的類來做,我寫了一個簡單的測試程序如下:
Java代碼 ?
解壓程序我也寫了,如下:
Java代碼 ?
我以為用修改后的my.java.util.zip.ZipOutputStream或my.java.util.zip.ZipInputStream就可以解決問題,我將這兩個類拷給同學,在他那里會出錯,原來這兩個類修改也包括了對它們引用到的類的修改,我現將它們打包發(fā)上來,導入就可以用了,中文名的壓縮和解壓縮的問題也可以解決了。
總結
以上是生活随笔為你收集整理的java压缩文件,中文问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据库实例服务被误删后
- 下一篇: 论优秀的码农,学会这5点!