java 解压有中文的zip文件出错

dexiliu 发布于 2015/06/26 15:33
阅读 2K+
收藏 0

这是一个在指定路径下载一个压缩包并解压的代码

有时会出错(下载每次都无问题,就是解压会出错),具体错误:

严重: Servlet.service() for servlet [spring-web] in context with path [/zngsgw] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: MALFORMED] with root cause
java.lang.IllegalArgumentException: MALFORMED
at java.util.zip.ZipCoder.toString(ZipCoder.java:58)
at java.util.zip.ZipInputStream.readLOC(ZipInputStream.java:297)
at java.util.zip.ZipInputStream.getNextEntry(ZipInputStream.java:121)
at com.zngsgw.ssh.controller.news.NewsController.unzip(NewsController.java:346)
at com.zngsgw.ssh.controller.news.NewsController.download(NewsController.java:247)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2442)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2431)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)


若把解压的那段代码单独放到一个main函数里跑也不会出错,每次都可以成功解压;但把下载和解压放在一起在tomcat服务器下跑就会出问题。找了很久都不知哪里出错,求高人指点!

刚找到原因,我的压缩包里有中文命名的文件,所以会有时成功,有时失败;若压缩包的所有文件名都没有中文,就可以不断下载并解压。现在就是请教,有中文命名的压缩包该如何可以成功解压。

具体代码如下:

@RequestMapping(params = "download")
public void download(HttpServletRequest request,HttpServletResponse response) throws IOException{

//下载
fileDownload(request,response);

//解压
unzip(new File(request.getRealPath("/")).getParent()+File.separator+"zngsgw.zip",
new File(request.getRealPath("/")).getParent()+File.separator);
}

//下载的具体代码

public void fileDownload(HttpServletRequest request,HttpServletResponse response)throws UnsupportedEncodingException{

response.setContentType("application/x-download");
File filePath=new File("d:/zngsgw.zip");//要下载的压缩文件
File savePath=new File(request.getRealPath("/"));
File save=new File(savePath.getParent()+"/zngsgw.zip");//下载压缩文件后保存的路径

FileOutputStream out=null;
FileInputStream in=null;

try{
out=new FileOutputStream(save);
in=new FileInputStream(filePath);

byte[] b=new byte[1024];
int i=0;

while((i=in.read(b))>0){
out.write(b);
out.flush();
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
in=null;
}
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
out=null;
}
}
}

/**
* 解压文件
* @param zipFilePath
* 需要 解压文件路径
* @param targetPath
* 解压到的路径
* @throws IOException
*/
@SuppressWarnings("resource")
public void unzip(String zipFilePath, String targetPath)
throws IOException {
OutputStream os = null;
InputStream is = null;
ZipFile zipFile = null;
ZipInputStream zipInputStream = null;
try {
zipFile = new ZipFile(zipFilePath, Charset.forName("gbk"));//解决文件目录有中文时的解压错误
String directoryPath = "";
if (null == targetPath || "".equals(targetPath)) {
directoryPath = zipFilePath.substring(0,zipFilePath.lastIndexOf("."));
} else {
directoryPath = targetPath;
}
zipInputStream = new ZipInputStream(new FileInputStream(
zipFilePath), Charset.forName("gbk"));//解决文件目录有中文时的解压错误
if (null != zipInputStream) {
ZipEntry zipEntry=null;
while ((zipEntry=zipInputStream.getNextEntry())!=null) {
if (zipEntry.getSize() > 0) {
File targetFile = buildFile(directoryPath + File.separator + zipEntry.getName(), false);
os = new BufferedOutputStream(new FileOutputStream(targetFile));
is = zipFile.getInputStream(zipEntry);
byte[] buffer = new byte[4096];
int readLen = 0;
while ((readLen = is.read(buffer, 0, 4096)) >= 0) {
os.write(buffer, 0, readLen);
}
os.flush();
} else {
buildFile(directoryPath + File.separator + zipEntry.getName(), true);
}
}
}
} catch (IOException ex) {
throw ex;
} finally {
if(null != zipInputStream){
zipInputStream.close();
zipInputStream=null;
}
if (null != is) {
is.close();
is=null;
}
if (null != os) {
os.close();
os=null;
}
}
}

public File buildFile(String fileName, boolean isDirectory) {
File target = new File(fileName);
if (isDirectory) {
target.mkdirs();
} else {
if (!target.getParentFile().exists()) {
target.getParentFile().mkdirs();
target = new File(target.getAbsolutePath());
}
}
return target;
}
加载中
返回顶部
顶部