这两天复习servlet,做文件上传,刚开始是这样写的
public class FileUploadServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
InputStream is = req.getInputStream();
String path = getServletContext().getRealPath("/uploads/a.jpg");
System.out.println(path);
File file = new File(path);
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
byte[] b = new byte[1024];
int n=0;
while((n=is.read(b))!=-1){
fos.write(b,0,n);
}
fos.close();
is.close();
}
}
发现上传图片等非文本文件是不能打开的,并且得到的文件比源文件要大,然后就想到用commons-fileupload来做上传,先上代码。
public class RegisterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//req.setCharacterEncoding("utf-8");已无用
DiskFileItemFactory factory = new DiskFileItemFactory();
<span style="white-space:pre"> //设置阀值
factory.setSizeThreshold(1024);</span>
ServletContext context = getServletContext();
//获取上传路径
String dir = context.getInitParameter("uploadDir");
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List<FileItem> items = upload.parseRequest(req);
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
FileItem item = iter.next();
//如果是普通的项
if (item.isFormField()) {
System.out.println(item.getFieldName());
//获取utf-8格式的值
System.out.println(item.getString("utf-8"));
}
//如果是文件项
else {
System.out.println(item.getFieldName());
InputStream is = item.getInputStream();
String path = getServletContext().getRealPath(dir);
//获取源文件的名字
File file = new File(path,item.getName());
if(!file.exists()){
file.createNewFile();
}
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[1024];
while((bytesRead = is.read(buffer, 0, 1024)) != -1){
os.write(buffer, 0, bytesRead);
}
os.close();
is.close();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
/**
* @param item
*/
private void processUploadedFile(FileItem item) {
}
/**
* @param item
*/
private void processFormField(FileItem item) {
}
简单看一下源码,commons-fileupload组件是对rfc1867协议(有兴趣的可以看一下)的java实现与扩展,。
当上传文件时会有一个阀值(threshold),低于阀值时文件保存在内存中,高于阀值会写在临时文件里,临时文件的路径由组件指定,,对于大文件上传这样可以节省内存,保存好之后,才是我们得到输入流来写入指定路径文件。