最近在做一个FTP文件下载的功能,包括单个文件下载和打包文件下载,但是代码写出来以后经过各种调试测试,发现无论单个文件下载还是打包文件下载,都无法使用迅雷下载,只能使用浏览器进行下载,而且在下载的过程中不会显示进度条,但是文件下载下来的文件是很正常的。
//单个文件下载
public void Ftpdownload(String reaName,String fileName,String remote,HttpServletResponse response,HttpServletRequest request) throws IOException
{
// 开启输出流弹出文件保存路径选择窗口
response.setContentType("application/octet-stream");
response.setContentType("application/OCTET-STREAM;charset=UTF-8");
//解决下载文件中文名称乱码的问题
String agent = request.getHeader("USER-AGENT");
if(agent != null && agent.toLowerCase().indexOf("firefox") > 0)
{
reaName = "=?UTF-8?B?" + (new String(Base64.encodeBase64(reaName.getBytes("UTF-8")))) + "?=";
}
else
{
reaName = java.net.URLEncoder.encode(reaName, "UTF-8");
}
response.setHeader("Content-Disposition", "attachment;filename=" +reaName);
OutputStream out = response.getOutputStream();
// 转移到FTP服务器目录至指定的目录下
ftpClient.changeWorkingDirectory(new String(remote.getBytes(LOCAL_CHARSET), SERVER_CHARSET));
//下载FTP服务器指定文件
ftpClient.retrieveFile(new String(fileName.getBytes(LOCAL_CHARSET), SERVER_CHARSET), out);
out.close();
}
//打包下载
public void download(Map<String,String> map,String isbn,HttpServletResponse response){
// 开启输出流弹出文件保存路径选择窗口
response.setContentType("application/octet-stream");
response.setContentType("application/OCTET-STREAM;charset=UTF-8");
//解决下载文件中文名称乱码的问题
try {
SimpleDateFormat simpleDateFormat;
simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
Date date = new Date();
String folderName=isbn+"-"+simpleDateFormat.format(date);
response.setHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(folderName+".zip", "UTF-8"));
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//设置缓存大小
byte[] buffer = new byte[1024];
OutputStream out;
try {
out = response.getOutputStream();
//开启压缩流
ZipOutputStream zipout = new ZipOutputStream(out);
int len;
FTPFile[] listFiles=ftpClient.listFiles();
Set<String> set = map.keySet();
List<InputStream> list = new ArrayList<InputStream>();
for (String key : set) {
// 转移到FTP服务器目录至指定的目录下
ftpClient.changeWorkingDirectory(new String(map.get(key)
.getBytes(LOCAL_CHARSET), SERVER_CHARSET));
String string = new String(key.getBytes(LOCAL_CHARSET),SERVER_CHARSET);
//从FTP服务器下载文件到文件流
InputStream retrieveFileStream = ftpClient
.retrieveFileStream(string);
//标记为压缩包中内的一个新文件
zipout.putNextEntry(new ZipEntry(key));
//写入输出流
while ((len = retrieveFileStream.read(buffer)) > 0) {
zipout.write(buffer, 0, len);
}
//关闭下载流
retrieveFileStream.close();
//FTP内置方法,必须调用才能下载下一个文件流
ftpClient.completePendingCommand();
}
//关闭压缩流
zipout.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
选择迅雷下载的时候,控制台会报如下错
org.apache.commons.net.io.CopyStreamException: IOException caught while copying.
at org.apache.commons.net.io.Util.copyStream(Util.java:135)
at org.apache.commons.net.ftp.FTPClient._retrieveFile(FTPClient.java:1800)
at org.apache.commons.net.ftp.FTPClient.retrieveFile(FTPClient.java:1769)
at com.snsoft.common.uitl.FtpUtils.download(FtpUtils.java:413)
at com.snsoft.resource.controller.OCmsController.downloadPicture(OCmsController.java:548)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
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.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
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:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:413)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:438)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:426)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91)
at org.apache.commons.net.io.Util.copyStream(Util.java:123)
... 44 more
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:240)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:119)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:517)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:408)
... 50 more
FtpUtils.java: 413行报错,看看是什么