DiskFileItemFactory和ServletFileUpload
1.DiskFileItemFactory
DiskFileItemFactory直接翻译就是磁盘文件项目工厂,也不难理解,它的功能就是给上传的文件提供一个内存空间或者磁盘空间临时存放一下。
它有一个默认大小,为10KB。
临时存储位置和大小可以自己设置,如不自己设置,则使用默认值
DiskFileItemFactory dfif = new DiskFileItemFactory();
自行设置如下:
DiskFileItemFactory(int sizeThreshold, File repository); // sizeThreshold :缓存大小 repository:临时文件存储位置
2.ServletFileUpload
ServletFileUpload是实现上传这个功能本身的方法,也就是一个上传工具。我们通过new一个ServletFileUpload,将上面创建好的项目工厂对象作为参数放进这个方法里。
ServletFileUpload sfu = new ServletFileUpload(dfif);
List<FileItem> items = sfu.parseRequest(request);
就是有文件要上传了,我们借由ServletFileUpload工具把它扔到DiskFileItemFactory里进行一些处理,再通过parseRequest分析这个文件所携带的信息。
3.isFormField()
判断FileItem是一个文件上传对象还是普通表单对象,它的值是boolean型。
3.1 isFormField()==true
如果是一个没有文件的普通表单对象的话,则可以通过 getFieldName() 获取表单name属性值,通过 getString(String encoding) 获得表单对象的value属性,用encoding进行编码设置。
3.2 isFormField()==false
如果是一个文件对象的话,则可以通过 getName() 获取文件名,通过 getInputStream() 获得文件的输入流
4.FileOutputStream()
当我们解析完文件信息之后,一方面需要把相关信息存入数据库相关表中,一方面需要把文件上传到真正的存储位置。
File对象代表磁盘中实际存在的文件和目录,我们通过java提供的File对象来设置文件存储路径。
例如:
File file = new File("D://test");
然后使用FileOutputStream(),在设置好的路径以vir_name存入(vir_name是我已经处理过的对象),最后我们得到的out对象就是一个完整的路径,例如:D://test//vir_name
OutputStream out = new FileOutputStream(file+"//"+vir_name);
紧接着我们就可以进行读写
以下是读写的代码,不过不是本篇重点不进行详细赘述
// 定义一个length用于接收文件真实文件字节长度
int length = 0;
byte[] temp = new byte[1024];
while ((length=is.read(temp))!=-1) {
os.write(temp,0,length);// 写入字节从0写到文件的真实字节数,这样就不会有往不够的地方填入的情况出现
}
以上是我的一点理解,如有错误欢迎大佬批评指正。
补充:感觉上面可能有点乱,下面贴上我的完整java代码
package com.sk.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.sk.dao.UploadFileDao;
import com.sk.pojo.FileInfo;
public class UploadFileServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 设定编码,防止乱码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
// DiskFileItemFactory 作用:可以设置缓存大小以及临时文件保存位置.
// DiskFileItemFactory(int sizeThreshold, File repository) sizeThreshold :缓存大小 repository:临时文件存储位置
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
// 创建一个上传工具,指定缓存区与临时文件存储位置
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
List<FileItem> list = null;
try {
// 解析request对象,得到所有上传项.每一个FileItem就相当于一个上传项
list = servletFileUpload.parseRequest(req);
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 以下定义的是需要存入数据库表中的数据信息
String file_id = UUID.randomUUID().toString();
String file_name = null;
String uploader = null;
String vir_name = null;
String size = null;
String type = null;
String path = null;
// 使用循环判断前端传来的表单信息
for (int i = 0; i < list.size(); i++) {
// 判断是否为普通的文本表单对象
if (list.get(i).isFormField()) {// 若为普通的文本表单对象,则获取文本对象的value值
if (list.get(i).getFieldName().equals("uploader")) {
uploader = list.get(i).getString("utf-8");
}
}else { // 若是文件对象则获取文件的相关信息
file_name = list.get(i).getName(); // 文件名
type = file_name.substring(file_name.lastIndexOf("."),file_name.length());// 从文件名里截取出后缀
vir_name = file_id + type; // 假名以文件id加后缀拼接
File file = new File("D://updowntest"); // 以现有文件夹作为目标目录
path = file+"//"+vir_name; // 路径,以上面的file+假名构成路径
// 获得上传文件的输入流
InputStream in = list.get(i).getInputStream();
// 判断大小,修改文件大小单位
if (list.get(i).getSize()/1024<1) {
size = String.valueOf(list.get(i).getSize())+"B";
}
if (list.get(i).getSize()/1024>=1&&list.get(i).getSize()/1024<1024) {
size = String.valueOf(list.get(i).getSize()/1024)+"KB";
}
if (list.get(i).getSize()/1024>=1024&&list.get(i).getSize()/1024<1024*1024) {
size = String.valueOf(list.get(i).getSize()/(1024*1024))+"MB";
}
// 创建文件信息类的对象,接收上述相关信息
FileInfo fileInfo = new FileInfo(file_id,file_name,uploader,vir_name,size,type,path);
try {
new UploadFileDao().uploadFile(fileInfo); // 调用UploadFileDao的uploadFile的方法,这就是将相关信息插入表中的操作
} catch (SQLException e) {
e.printStackTrace();
}
// 创建文件的输出流
OutputStream out = new FileOutputStream(file+"//"+vir_name);
// 读写操作
int length = 0;// 定义length获取真实的文件长度
byte[] temp = new byte[1024];
while ((length=in.read(temp))!=-1) {
out.write(temp);
}
// 刷新并释放资源
out.flush();
out.close();
in.close();
}
}
resp.getWriter().print("{\"code\":\"0\"}");
}
}