刚开始搞文件上传的时候想法很简单,文件上传嘛,在servlet里写个方法,找到文件目录,new个inputstream,就ok 啦。现在想想好幼稚。
最近看了几篇帖子,对文件上传有了一定了解。既然要从客户端上传到服务器,肯定需要数据流啦。而在servlet规范中,能携带客户端东东的也就是个servletRequest了,public ServletInputStream getInputStream()(Retrieves the body of the request as binary data using a ServletInputStream
.),这个方法有个输入流。既然这样,就用它试试吧
<%@ page language="java" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'fileupload.jsp' starting page</title>
</head>
<body>
<!-- enctype 默认是 application/x-www-form-urlencoded -->
<form action="SimpleFileUpload" enctype="multipart/form-data" method="post">
用户名:
<input type="text" name="usename">
<br />
上传文件:
<input type="file" name="file1">
<br />
<input type="submit" value="提交" />
</form>
</body>
</html>
再后台写个SimpleFileUploadServlet.java
package com.servlet.fileupload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@SuppressWarnings("serial")
public class SimpleFileUpload extends HttpServlet {
@SuppressWarnings("deprecation")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
InputStream in = request.getInputStream();
String path = request.getRealPath("/upload");
//貌似上传文件的名字咋取? 先随便命个名吧
OutputStream out = new FileOutputStream(new File(path, "test"));
int length = 0;
byte[] buf = new byte[1024];
// in.read(buf) 每次读到的数据存放在 buf 数组中
while ((length = in.read(buf)) != -1) {
// 在 buf 数组中 取出数据 写到 (输出流)磁盘上
out.write(buf, 0, length);
}
in.close();
out.close();
request.getRequestDispatcher("filedemo.jsp").forward(request, response);
}
}
然后,在桌面上创建一个文件,o.txt,里面写一行内容,就写abcdefg吧。
部署好应用,提交下jsp页面,去tomcat 部署的应用下找upload文件夹,里面确实有了个叫test的文件,打开内容一看:
-----------------------------7dc1653a400386
Content-Disposition: form-data; name="usename"
sdf
-----------------------------7dc1653a400386
Content-Disposition: form-data; name="file1"; filename="C:\Documents and Settings\li\桌面\o.txt"
Content-Type: text/plain
abcdefg
-----------------------------7dc1653a400386--
我的o.txt的内容原来是abcdefg,现在怎么多出了这么多东东。不过还好,里面还有我原来的内容。
其实这就涉及到一些文件上传的规范了,推荐一篇文章http://blog.csdn.net/xiaojianpitt/article/details/6856536
这只是上传一个文本文件,如果是其他类型的文件呢,如果上传不只是一个文件呢?看来从输入流中解析出上传的文件好复杂,还好,这个倒是不用我们操心了,文件长传的开源工具早就有了,只有你想不到的,没有做不到的。
commons-fileupload-1.2.1.jar 就提供了完整的上传功能,很多提取文件和表单数据的工作都由它来完成了,他就像一台联合收割机,面对一片麦地,如何提取出想要的麦粒,这个不用你操心了,你只需要驾驭者它去收割就行了,看到机器储存器里快满了,就把他倒出来接着收割就行了。
大致介绍下几个类吧:
FileItem ,这个一个接口类,它是从输入流这个混沌中解析数来的清晰的数据,它代表了一个文件或者input等表单项。它存在于内存中或者磁盘上,如果在磁盘上的话,他只是一个以.tmp结尾的临时文件。子类:DiskFileItem
FileItemFactory :工厂接口,负责创建FileItem。他又一个关键 成员,sizeThreshold,他设置内存大小,如果一个FileItem超出了这个阀值,就把他写到磁盘上,以临时文件的形式保存。子类:DiskFileItemFactory
FileUploadBase :抽象类,不过关键方法都在此类实现。它相当于一个控制类,看类名 FileUpload 就是一个动词,文件上传,所以它是整个处理过程的执行者。子类:ServletFileUpload
还有其他一些类:如FileItemStream,MultipartStream等,都是在处理过程中需要的借助的类。
我们在编写的时候只需要上面几个类就够了
举例:网上看了篇帖子,有详细代码实现
http://blog.csdn.net/fly_buf/article/details/6541958
欢迎指正!