java解压缩zip文件时文件内中文部分乱码
RT 网上说用org.apache.tools.zip可以解决,我用后没有效果(注释掉的部分)。代码如下,求指教
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.Enumeration;
import java.util.zip.ZipInputStream;
import de.innosystec.unrar.Archive;
import de.innosystec.unrar.rarfile.FileHeader;
//import org.apache.tools.zip.ZipEntry;
//import org.apache.tools.zip.ZipFile;
//import org.apache.tools.zip.ZipOutputStream;
public class UnRarUtil
{
private static void unRar(String srcRar,String destDir) throws Exception
{
Archive a =null;
FileOutputStream fos = null;
try{
a = new Archive(new File(srcRar));
FileHeader fh = a.nextFileHeader();
while(fh != null)
{
if(!fh.isDirectory())
{
//根据不同的操作系统取得相应的destFileName,destDirNamme
String compressFileName = fh.getFileNameString().trim();
String destFileName = "";
String destDirNamme = "";
//非windows操作系统
if(File.separator.equals("/"))
{
destFileName = destDir + compressFileName.replaceAll("\\\\", "/");
destDirNamme = destFileName.substring(0, destFileName.lastIndexOf("/"));
}
else//windows系统
{
destFileName = destDir + compressFileName.replaceAll("/", "\\\\");
destDirNamme = destFileName.substring(0, destFileName.lastIndexOf("\\"));
}
File dir = new File(destDirNamme);
if(!dir.exists() || !dir.isDirectory())
{
dir.mkdirs();
}
fos = new FileOutputStream(new File(destFileName));
a.extractFile(fh, fos);
fos.close();
fos = null;
}
fh = a.nextFileHeader();
}
a.close();
a = null;
}
catch(Exception e){
throw e;
}
finally{
if(fos != null)
{
try{
fos.close();
fos = null;
}
catch(Exception e){
e.printStackTrace();
}
}
if(a != null)
{
try{
a.close();
a = null;
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
public static void doCompress(String srcFile,String destDir) throws Exception
{
//保证文件夹路径最后是"\"或者"/"
char lastChar = destDir.charAt(destDir.length()-1);
if(lastChar != '\\' && lastChar != '/')
{
destDir += File.separator;
}
//根据类型进行相应的解压
String type = srcFile.substring(srcFile.lastIndexOf(".")+1);
if(type.endsWith("zip"))
{
unZip(srcFile,destDir);
}
else if(type.endsWith("rar"))
{
UnRarUtil.unRar(srcFile, destDir);
}
else
{
throw new Exception("只支持zip和rar格式的压缩包!");
}
}
public static void unZip(String unZipfileName, String mDestPath) {
if (!mDestPath.endsWith("/"))
{
mDestPath = mDestPath + "/";
}
FileOutputStream fileOut = null;
ZipInputStream zipIn = null;
ZipEntry zipEntry = null;
File file = null;
int readedBytes = 0;
byte buf[] = new byte[4096];
try {
zipIn = new ZipInputStream(new BufferedInputStream(new FileInputStream(unZipfileName)));
while ((zipEntry = zipIn.getNextEntry()) != null)
{
file = new File(mDestPath + zipEntry.getName());
if (zipEntry.isDirectory())
{
file.mkdirs();
} else
{
// 如果指定文件的目录不存在,则创建之.
File parent = file.getParentFile();
if (!parent.exists())
{
parent.mkdirs();
}
fileOut = new FileOutputStream(file);
while ((readedBytes = zipIn.read(buf)) > 0)
{
fileOut.write(buf, 0, readedBytes);
}
fileOut.close();
}
zipIn.closeEntry();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
// public static void unZip(String zipfile, String destDir)
// {
// byte b[] = new byte [1024];
// int length;
// ZipFile zipFile;
// try {
//
// zipFile = new ZipFile( new File(zipfile,"GBK"));
//
// Enumeration<?> enumeration = zipFile.getEntries();
// ZipEntry zipEntry = null ;
// while (enumeration.hasMoreElements())
// {
// zipEntry = (ZipEntry) enumeration.nextElement();
// File loadFile = new File(destDir + zipEntry.getName());
//
//
//
// if (zipEntry.isDirectory()) {
//
// // 这段都可以不要,因为每次都貌似从最底层开始遍历的
//
// loadFile.mkdirs();
//
// } else {
//
// if (!loadFile.getParentFile().exists())
//
// loadFile.getParentFile().mkdirs();
//
//
//
// OutputStream outputStream = new FileOutputStream(loadFile);
//
// InputStream inputStream = zipFile.getInputStream(zipEntry);
//
//
//
// while ((length = inputStream.read(b)) > 0)
//
// outputStream.write(b, 0, length);
//
//
//
// }
//
// }
//
// System. out .println( " 文件解压成功 " );
//
// } catch (IOException e) {
//
// // TODO Auto-generated catch block
//
// e.printStackTrace();
//
// }
//
//
//
// }
}
[解决办法]
其实还是字符集问题,参考下这里解决吧:
http://hi.baidu.com/wqj403/blog/item/b90b2537c73c7e380855a962.html
[解决办法]
package com.*.*.server.resource.utils;import java.io.OutputStream;import java.io.IOException;import java.lang.reflect.Field;import java.util.Date;import java.util.Vector;import java.util.HashSet;import java.util.zip.CRC32;import java.util.zip.Deflater;import java.util.zip.DeflaterOutputStream;import java.util.zip.ZipException;/** * *此类从JDK中复制出来,添加了对中文文件名的支持 * * @author zengj * @version [版本号, 2012-2-9] * @see [相关类/方法] * @since [产品/模块版本] */public class CNZipOutPutStream extends DeflaterOutputStream implements ZipConstants{ private static class XEntry { public final ZipEntry entry; public final long offset; public final int flag; public XEntry(ZipEntry entry, long offset) { this.entry = entry; this.offset = offset; this.flag = (entry.method == DEFLATED && (entry.size == -1 || entry.csize == -1 || entry.crc == -1)) // store size, compressed size, and crc-32 in data descriptor // immediately following the compressed entry data ? 8 // store size, compressed size, and crc-32 in LOC header : 0; } } private XEntry current; private Vector<XEntry> xentries = new Vector<XEntry>(); private HashSet<String> names = new HashSet<String>(); private CRC32 crc = new CRC32(); private long written = 0; private long locoff = 0; private String comment; private int method = DEFLATED; private boolean finished; private boolean closed = false; private String fileNameEncoding = "UTF-8"; private static int version(ZipEntry e) throws ZipException { switch (e.getMethod()) { case DEFLATED: return 20; case STORED: return 10; default: throw new ZipException("unsupported compression method"); } } /** * Checks 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 CNZipOutPutStream(OutputStream out) { super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true)); try { Field f = this.getClass().getDeclaredField("usesDefaultDeflater"); f.setAccessible(true); f.set(this, true); } catch (NoSuchFieldException e) { // Ignore } catch (IllegalAccessException e) {// Ignore } } /** *此方法扩展了JDK的ZIP压缩输出流的默认构造函数,添加了一个内部文件名编码参数 */ public CNZipOutPutStream(OutputStream out, String fileNameEncoding) { this(out); if (fileNameEncoding != null) { this.fileNameEncoding = fileNameEncoding; } }