java FTP下载文件在代码中如何实现知道下载完成?
public static void downloadFileFtp(KmConfig kmConfig,String fileName, String clientFileName, OutputStream outputStream){
try {
String ftpHost = kmConfiggetFtpHost();
int port = kmConfiggetFtpPort();
String userName = kmConfiggetFtpUser();
String passWord = kmConfiggetFtpPassword();
String path = kmConfiggetFtpPath();
FtpClient ftpClient = new FtpClient(ftpHost, port);// ftpHost为FTP服务器的IP地址,port为FTP服务器的登陆端口,ftpHost为String型,port为int型。
ftpClientlogin(userName, passWord);// userName、passWord分别为FTP服务器的登陆用户名和密码
ftpClientbinary();
ftpClientcd(path);// path为FTP服务器上保存上传文件的路径。
try {
TelnetInputStream in = ftpClientget(fileName);
byte[] bytes = new byte[1024];
int cnt=0;
while ((cnt=inread(bytes,0,byteslength)) != -1) {
outputStreamwrite(bytes, 0, cnt);
}
//##############################################
//这里文件就已经下载完了,自己理解一下
//#############################################
outputStreamclose();
inclose();
} catch (Exception e) {
ftpClientcloseServer();
eprintStackTrace();
}
ftpClientcloseServer();
} catch (Exception e) {
Systemoutprintln("下载文件失败!请检查系统FTP设置,并确认FTP服务启动");
}
}
你的服务器是什么规范?HTTP?FTP?还是说要顺便写一个服务端出来?
如果是要写服务端的,自己搜索,网上有。
如果是HTTP协议和FTP协议的,java版本的见代码
InputStream ios=new URL("http://19216811/文件bomzip所在的WEB目录/bomzip")openConnection()getInputStream();
BufferedOutputStream bout=new BufferedOutputStream(new FileOutputStream("c:/存放目录/bomzip"));
byte buff[]=new byte[1024];
int count;
while((count=iosread(buff))>0){
boutwrite(buff, 0, count);
}
iosclose();
boutclose();
如果要C的话,用socket做,看一下HTTP协议规范,很简单可以做到文件传输的。
在Javaweb中,上传下载是经常用到的功能,对于文件上传,浏览器在上传的过程中是以流的过程将文件传给服务器,一般都是使用commons-fileupload这个包实现上传功能,因为commons-fileupload依赖于commons-io这个包,所以需要下载这两个包commons-fileupload-121jar和commons-io-132jar。
1、搭建环境
创建Web项目,将包导入到项目lib下
2、实现文件上传
(第一种上传的方法)
新建uploadjsp页面
12345678910111213141516<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 401 Transitional//EN" "http://wwww3org/TR/html4/loosedtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>upload file</title></head><body> <!--这里的<%=requestgetContextPath()%>是表示项目的绝对路径,也就是说不管你以后将项目拷贝到哪个位置,它都会找到准确的路径 --> <form action="<%=requestgetContextPath()%>/uploadServlet" enctype="multipart/form-data" method="post"> <span>选择文件:</span><input type="file" name="file1"> <input type="submit" value="上传"> </form></body></html>新建处理文件上传的Servlet
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667package comload; import javaioFile;import javaioIOException;import javautilList;import javaxservletServletContext;import javaxservletServletException;import javaxservletannotationWebServlet;import javaxservlethttpHttpServlet;import javaxservlethttpHttpServletRequest;import javaxservlethttpHttpServletResponse;import orgapachecommonsfileuploadFileItem;import orgapachecommonsfileuploadFileUploadException;import orgapachecommonsfileuploaddiskDiskFileItemFactory;import orgapachecommonsfileuploadservletServletFileUpload;@WebServlet("/uploadServlet")public class uploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public uploadServlet() { super(); } / fileupload 包中, HTTP 请求中的复杂表单元素都被看做一个 FileItem 对象; FileItem 对象必须由 ServletFileUpload 类中的 parseRequest() 方法解析 HTTP 请求 (即被包装之后的 HttpServletRequest 对象)出来,即分离出具体的文本表单和上传文件 / protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过isMultipartContent()方法:分析请求里面是不是有文件上的请求, boolean isMultipart = ServletFileUploadisMultipartContent(request); if(isMultipart){ //创建可设置的磁盘节点工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //获取请求的上下文信息 ServletContext servletContext = requestgetServletContext(); //缓存目录,每个服务器特定的目录 File repository = (File) servletContextgetAttribute("javaxservletcontexttempdir"); //设置服务器的缓存目录 factorysetRepository(repository); //ServletFileUpload 对象的创建需要依赖于 FileItemFactory //工厂将获得的上传文件 FileItem 对象保存至服务器硬盘,即 DiskFileItem 对象。 ServletFileUpload upload = new ServletFileUpload(factory); try { //解析即被包装之后的 HttpServletRequest对象,既是分离文本表单和上传文件(http请求会被包装为HttpServletRequest) List<FileItem> items = uploadparseRequest(request); for(FileItem item:items){ String fieldName = itemgetFieldName(); String fileName = itemgetName(); String contentType = itemgetContentType(); boolean isInMemory = itemisInMemory(); long sizeInBytes = itemgetSize(); //实例化一个文件 //requestgetRealPath(获取真实路径) File file = new File(requestgetRealPath("/")+"/loads"+fileNamesubstring(fileNamelastIndexOf("\\")+1,fileNamelength())); itemwrite(file); } } catch (FileUploadException e) { eprintStackTrace(); } catch (Exception e) { eprintStackTrace(); } } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}(第二种上传的方法)
新建Jsp页面(同上,只是路径改变下)
12345678910111213141516<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 401 Transitional//EN" "http://wwww3org/TR/html4/loosedtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>upload file</title></head><body> <!--这里的<%=requestgetContextPath()%>是表示项目的绝对路径,也就是说不管你以后将项目拷贝到哪个位置,它都会找到准确的路径 --> <form action="<%=requestgetContextPath()%>/uploadservlet1" enctype="multipart/form-data" method="post"> <span>选择文件:</span><input type="file" name="file1"> <input type="submit" value="上传"> </form></body></html>建立Servlet处理上传
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263package comload; import javaioFile;import javaioFileOutputStream;import javaioIOException;import javaioInputStream;import javaioOutputStream;import javaxservletServletException;import javaxservletannotationMultipartConfig;import javaxservletannotationWebServlet;import javaxservlethttpHttpServlet;import javaxservlethttpHttpServletRequest;import javaxservlethttpHttpServletResponse;import javaxservlethttpPart;@WebServlet("/uploadservlet1")@MultipartConfig(location="")public class uploadservlet1 extends HttpServlet { private static final long serialVersionUID = 1L; public uploadservlet1() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { responsesetContentType("text/html;charset=UTF-8"); requestsetCharacterEncoding("utf-8"); //取得上传文件,读取文件 Part part = requestgetPart("file1"); //定义一个变量去接收文件名 String filename = null; //Content-Disposition: 就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名 //Content-Disposition:告诉浏览器以下载的方式打开文件 for (String content : partgetHeader("content-disposition")split(";")) { Systemoutprintln(content); //取得文件名 if (contenttrim()startsWith("filename")) { //截取文件名 filename = contentsubstring( contentindexOf('=') + 1)trim()replace("\"", ""); } } //输出流 OutputStream out = null; //输入流 InputStream filecontent = null; //Fileseparator 取得系统的分割线等数据 out = new FileOutputStream(new File("e:/loads" + Fileseparator + filename)); int read; //获得一个输入流 filecontent = partgetInputStream(); final byte[] bytes = new byte[1024]; while ((read = filecontentread(bytes)) != -1) { outwrite(bytes, 0, read); } Systemoutprintln("New file " + filename + " created at " + "/loads"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); }}(第三种上传的方法)
这里使用的是jspSmartUpload包上传下载,笔者认为这种上传下载较为简单,但是好像不是很多人用,不懂。
创建HTML页面
123456789101112131415161718192021222324252627<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>上传文件</title></head><body> <p> </p> <p align="center">上传文件选择</p> <form method="post" Action="/DouploadServlet" enctype="multipart/form-data"> <table width="75%" border="1" align="center"> <tr><td><div align="center"> 1<input type="file" name="file1" > </div></td></tr> <tr><td><div align="center"> 2<input type="file" name="file2" > </div></td></tr> <tr><td><div align="center"> 3<input type="file" name="file3" > </div></td></tr> <tr><td><div align="center"> <input type="submit" name="Submit" value="上传他"> </div></td></tr> </table> </form></body></html>创建Servlet处理上传文件
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182package comload; import javaioIOException;import javaioPrintWriter; import javaxservletServletException;import javaxservletannotationWebServlet;import javaxservlethttpHttpServlet;import javaxservlethttpHttpServletRequest;import javaxservlethttpHttpServletResponse;import javaxservletjspJspFactory;import javaxservletjspPageContext; import comjspsmartuploadFile;import comjspsmartuploadSmartUpload;import comjspsmartuploadSmartUploadException;@WebServlet("/DouploadServlet")public class DouploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DouploadServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { responsesetContentType("text/html;charset=UTF-8"); PrintWriter out = responsegetWriter(); //新建一个智能上传对象 SmartUpload su = new SmartUpload(); / PageContext pageContext; HttpSession session; ServletContext application; ServletConfig config; JspWriter out; Object page = this; HttpServletRequest request, HttpServletResponse response 其中page对象,request和response已经完成了实例化,而其它5个没有实例化的对象通过下面的方式实例化 pageContext = jspxFactorygetPageContext(this, request, response,null, true, 8192, true); / //通过Jsp工厂类获取上下文环境 PageContext pagecontext = JspFactorygetDefaultFactory()getPageContext(this, request, response, null, true, 8192, true); //上传初始化 suinitialize(pagecontext); //上传文件 try { suupload(); //将上传文件保存到指定目录 int count = susave("/share"); outprintln(count+"个文件上传成功!<br>"+sutoString()); } catch (SmartUploadException e) { eprintStackTrace(); } //逐个提取上传文件信息 for(int i=0;i<sugetFiles()getCount();i++){ File file = sugetFiles()getFile(i); //如果文件不存在 if(fileisMissing()) continue; //显示当前文件信息 outprintln("<table border=1>"); outprintln("<tr><td>表单项名(FieldName)</td></td>"+filegetFieldName()+"</td></tr>"); outprintln("<tr><td>文件长度</td><td>"+filegetSize()+"</td></tr>"); outprintln("<tr><td>文件名</td><td>"+filegetFileName()+"</td></tr>"); outprintln("<tr><td>文件扩展名</td><td>"+filegetFileExt()+"</td></tr>"); outprintln("<tr><td>文件全名</td><td>"+filegetFilePathName()+"</td></tr>"); outprintln("</table><br>"); } } / @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) / protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }注意:代码 int count = susave("/share");表示你需要先建个文件夹,所以你可以先在Webcontent建立一个,然后将项目取消部署,再重新部署进去之后就会在运行那边建立起一个文件夹了!
或者你可以直接找到运行的路径,然后建立share文件夹。
3、实现文件下载
(第一种文件下载)
注意:该代码是直接访问Servlet类的
123456789101112131415161718192021222324252627282930313233343536373839404142package comload; import javaioFileInputStream;import javaioIOException;import javaioInputStream;import javaioOutputStream; import javaxservletServletException;import javaxservletannotationWebServlet;import javaxservlethttpHttpServlet;import javaxservlethttpHttpServletRequest;import javaxservlethttpHttpServletResponse; //直接使用Http://localhost:8080/Test1/download进行下载,但是这个有缺陷,如果下载文件名中有中文,就会变成乱码现象!@WebServlet("/download")public class download extends HttpServlet { private static final long serialVersionUID = 1L; public download() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { responsesetContentType("text/plain;charset=utf-8"); responsesetCharacterEncoding("utf-8"); responsesetHeader("Location","中文txt"); responsesetHeader("Content-Disposition", "attachment; filename=" + "账号txt"); OutputStream outputStream = responsegetOutputStream(); InputStream inputStream = new FileInputStream("E:/loads"+"/账号txt"); byte[] buffer = new byte[1024]; int i = -1; while ((i = inputStreamread(buffer)) != -1) { outputStreamwrite(buffer, 0, i); } outputStreamflush(); outputStreamclose(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }(第二种下载方法)
新建jsp页面选择下载
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 401 Transitional//EN" "http://wwww3org/TR/html4/loosedtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>下载</title></head><body> <a href="/DoDownloadServletfilename=呵呵txt">点击下载</a></body></html>创建Servlet类进行下载(注意:该下载如果文件名是中文的话,一样会出现乱码现象)
package comload;
import javaioBufferedInputStream;import javaioFile;import javaioFileInputStream;import javaioIOException;import javaioInputStream;import javaioOutputStream;import javanetURLEncoder; import javaxservletServletException;import javaxservletannotationWebServlet;import javaxservlethttpHttpServlet;import javaxservlethttpHttpServletRequest;import javaxservlethttpHttpServletResponse;import javaxservletjspJspFactory;import javaxservletjspPageContext; import orghsqldblibStringUtil; import comjspsmartuploadSmartUpload;import comjspsmartuploadSmartUploadException; @WebServlet("/DoDownloadServlet")public class DoDownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DoDownloadServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //得到下载文件的名称 //String filename = requestgetParameter("filename"); //String filename = new String(FileNamegetBytes("iso8859-1"),"UTF-8"); //新建SmartUpload对象 SmartUpload su = new SmartUpload(); PageContext pagecontext = JspFactorygetDefaultFactory()getPageContext(this, request, response, null, true, 8192, true); //上传初始化 suinitialize(pagecontext); //设置禁止打开该文件 susetContentDisposition(null); //下载文件 try { sudownloadFile("/listener/"+filename); } catch (SmartUploadException e) { // TODO Auto-generated catch block eprintStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}(第三种下载的方法)
同上的jsp页面代码,这里就不再重复了。
新建Serlvet类,实现下载功能(注意:这里文件名就算是中文名,也不会出现乱码问题了!)
package comload;
import javaioBufferedInputStream;import javaioFile;import javaioFileInputStream;import javaioIOException;import javaioInputStream;import javaioOutputStream;import javanetURLEncoder; import javaxservletServletException;import javaxservletannotationWebServlet;import javaxservlethttpHttpServlet;import javaxservlethttpHttpServletRequest;import javaxservlethttpHttpServletResponse;import javaxservletjspJspFactory;import javaxservletjspPageContext; import orghsqldblibStringUtil; import comjspsmartuploadSmartUpload;import comjspsmartuploadSmartUploadException; @WebServlet("/DoDownloadServlet")public class DoDownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DoDownloadServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得文件名称 String path1 = requestgetParameter("filename"); //获得路径名称 String path = requestgetSession()getServletContext()getRealPath("/listener/"+path1); // path是根据日志路径和文件名拼接出来的 File file = new File(path); String filename = filegetName(); try { //判断是否是IE11 Boolean flag= requestgetHeader("User-Agent")indexOf("like Gecko")>0; //IE11 User-Agent字符串:Mozilla/50 (Windows NT 61; WOW64; Trident/70; rv:110) like Gecko //IE6~IE10版本的User-Agent字符串:Mozilla/50 (compatible; MSIE 100; Windows NT 60; Trident/60) if (requestgetHeader("User-Agent")toLowerCase()indexOf("msie") >0||flag){ filename = URLEncoderencode(filename, "UTF-8");//IE浏览器 }else { //先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码, //这个文件名称用于浏览器的下载框中自动显示的文件名 filename = new String(filenamereplaceAll(" ", "")getBytes("UTF-8"), "ISO8859-1"); //firefox浏览器 //firefox浏览器User-Agent字符串: //Mozilla/50 (Windows NT 61; WOW64; rv:360) Gecko/20100101 Firefox/360 } InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer; buffer = new byte[fisavailable()]; fisread(buffer); fisclose(); responsereset(); responseaddHeader("Content-Disposition", "attachment;filename=" +filename); responseaddHeader("Content-Length", "" + filelength()); OutputStream os = responsegetOutputStream(); responsesetContentType("application/octet-stream"); oswrite(buffer);// 输出文件 osflush(); osclose(); } catch (IOException e) { eprintStackTrace(); } Systemoutprintln(filename); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }}向压缩包里添加文件时直接把服务器上的文件用流读进来就行,不用非把文件放到同一个目录,用程序生成压缩包和用命令行工具是不一样的,不要想当然。 写了个示例程序,你可以参考一下。这个示例不使用临时文件,把 OutputStream os替换成你下载用的输出流就可以实现一边压缩一边下载。注意javautilzip不支持非ascii文件名。想支持中文文件名可以用apache ant或其他的库。
import javaio;
import javautilzipZipEntry;
import javautilzipZipOutputStream;
public class ZipTest {
public static void main( String[] args ) {
try {
writeZip();
} catch ( IOException e ) {
eprintStackTrace();
}
}
private static void writeZip() throws IOException {
String[] files = { "/ws/dir1/file1", "/ws/dir2/file2", "/ws/file3", "/pub/successwav" };
OutputStream os = new BufferedOutputStream( new FileOutputStream( "/ws/archivezip" ) );
ZipOutputStream zos = new ZipOutputStream( os );
byte[] buf = new byte[8192];
int len;
for ( String filename : files ) {
File file = new File( filename );
if ( !fileisFile() ) continue;
ZipEntry ze = new ZipEntry( filegetName() );
zosputNextEntry( ze );
BufferedInputStream bis = new BufferedInputStream( new FileInputStream( file ) );
while ( ( len = bisread( buf ) ) > 0 ) {
zoswrite( buf, 0, len );
}
zoscloseEntry();
}
zosclose();
}
}
写个文件专门提供下载文件也可以,但那样对于你这种情况明显多余了,把服务器端Excel文件的MIME类型映射信息改成application/octet-stream即可。这个映射可以在webxml中定义。
0条评论