文件的上传
首先了解DiskFileItemFactory类
package org.apache.commons.fileupload.disk;
import org.apache.commons.fileupload.FileItemFactory;
属性
public static final int DEFAULT_SIZE_THRESHOLD = 10240;将文件保存在内存还是磁盘临时文件夹的默认临界值,值为10240,即10kb。
private File repository;用于配置在创建文件项目时,当文件项目大于临界值时使用的临时文件夹,默认采用系统默认的临时文件路径, 可以通过系统属性 java.io.tmpdir获取。如下代码:
System.getProperty("java.io.tmpdir");
private int sizeThreshold = DEFAULT_SIZE_THRESHOLD;
/**
* Sets the size threshold beyond which files are written directly to disk.
*
* @param sizeThreshold The size threshold, in bytes.
*
* @see #getSizeThreshold()
*
*/
public void setSizeThreshold(int sizeThreshold) {
this.sizeThreshold = sizeThreshold;
}
Apache文件上传组件在解析上传数据中的每个字段内容时,需要临时保存解析出的数据,以便在后面进行数据的进一步处理 (保存在磁盘特定位置或插入数据库)。因为Java虚拟机默认可以使用的内存空间是有限的,超出限制时将会抛出“java.lang.OutOfMemoryError”错误。如果上传的文件很大,例如800M的文件,在内存中将无法临时保存该文件内容,Apache文件上传组件转而采用临时文件来保存这些数据;但如果上传的文件很小,例如600个字节的文件,显然将其直接保存在内存中性能会更加好些。
setSizeThreshold方法用于设置是否将上传文件已临时文件的形式保存在磁盘的临界值(以字节为单位的int值),如果从没有调用该方法设置此临界值,将会采用系统默认值10KB。对应的getSizeThreshold() 方法用来获取此临界值。
/**
* Sets the directory used to temporarily store files that are larger
* than the configured size threshold.
*
* @param repository The directory in which temporary files will be located.
*
* @see #getRepository()
*
*/
public void setRepository(File repository) {
this.repository = repository;
}
setRepositoryPath方法用于设置当上传文件尺寸大于setSizeThreshold方法设置的临界值时,将文件以临时文件形式保存在磁盘上的存放目录。有一个对应的获得临时文件夹的 File getRespository() 方法。
注意:当从没有调用此方法设置临时文件存储目录时,默认采用系统默认的临时文件路径,可以通过系统属性 java.io.tmpdir 获取。如下代码:
System.getProperty("java.io.tmpdir");
Tomcat系统默认临时目录为“<tomcat安装目录>/temp/”。
try {
// 1,生成文件上传工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 2,利用工厂生成文件上传核心类
ServletFileUpload fileUpload = new ServletFileUpload(factory);
// 3,利用上传核心类,解析request对象从请求正文中 分析出fileItem
List<FileItem> itemList = fileUpload.parseRequest(request);
for(FileItem item:itemList){
if(item.isFormField()){
//说明当前的item是普通的字段项
String name=item.getFieldName();
String value=item.getString();
System.out.println(name+":"+value);
}else{
//说明当前的item是文件上传
String fileName=item.getName();
String path=this.getServletContext().getRealPath("/upload");
InputStream in=item.getInputStream();
FileOutputStream out=new FileOutputStream(new File(path,fileName));
IOUtils.in2out(in, out);
IOUtils.close(in, out);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
ServletFileUpload类
在 fileupload 包中, HTTP 请求中的复杂表单元素都被看做一个 FileItem 对象;FileItem 对象必须由 ServletFileUpload
类中的 parseRequest() 方法解析 HTTP 请求(即被包装之后的 HttpServletRequest 对象)出来,即分离出具体的文本表单
和上传文件;而 ServletFileUpload 对象的创建需要依赖于 FileItemFactory 工厂将获得的上传文件 FileItem 对象保存至
服务器硬盘,即 DiskFileItem 对象。
// 2,利用工厂生成文件上传核心类
ServletFileUpload fileUpload = new ServletFileUpload(factory);
// 判断当前表单是否是一个正确的文件上传表单
if (!fileUpload.isMultipartContent(request)) {
throw new RuntimeException("请使用正确的文件上传表单进行文件上传!");
}
// 设置生成单个文件的最大值
fileUpload.setFileSizeMax(1024 * 1024 * 270);
// --限制文件上传总文件的最大值
fileUpload.setSizeMax(1024 * 1024 * 500);
//设置编码集解决文件名乱码问题;
fileUpload.setHeaderEncoding("utf-8");