上传文件—fileupload工具—细节处理
2016-10-26 00:00
330 查看
上传文件—fileupload工具—细节处理
一.Tip:上传文件的处理细节1.中文文件乱码问题
文件名中文乱码问题,可调用ServletUpLoader的setHeaderEncoding方法,或者设置request的setCharacterEncoding属性
普通字段的乱码:
1.手工转换
2.FileItem.getString("UTF-8");获得名称的时候传一个字符集
上传文件的乱码: ServletFileUpload.setHeaderEncoding("UTF-8");
2.临时文件的删除问题
由于文件大小超出DiskFileItemFactory.setSizeThreshold方法设置的内存缓冲区的大小时,Commons-fileupload组件将使用临时文件保存上传数据,因此在程序结束时,务必调用FileItem.delete方法删除临时文件。
在处理完每一个item之后,要记得调用item.delete方法,删除临时文件
Delete方法的调用必须位于流关闭之后,否则会出现文件占用,而导致删除失败的情况。
3.文件存放位置
为保证服务器安全,上传文件应保存在应用程序的WEB-INF目录下,或者不受WEB服务器管理的目录。
为防止多用户上传相同文件名的文件,而导致文件覆盖的情况发生,文件上传程序应保证上传文件具有唯一文件名。
为防止单个目录下文件过多,影响文件读写速度,处理上传文件的程序应根据可能的文件上传总量,选择合适的目录结构生成算法,将上传文件分散存储。
4.如何处理空文件上传
在处理item时,判断item的getName方法返回的是不是"",如果为空,则代表客户机没有上传文件
5.限制上传文件的最大值
限制单个的最大值:upload.setFileSizeMax(1024*1024); FileUploadBase.FileSizeLimitExceededException
限制多个的最大值:upload.setSizeMax(1024*1024*5); FileUploadBase.SizeLimitExceededException
6.为防止多用户上传相同文件名的文件,而导致文件覆盖的情况发生,文件上传程序应保证上传文件具有唯一文件名。
public String generateFilename(String filename){
return UUID.randomUUID().toString() + "_" + filename; //83743_9834834_9u34_9834-1.avi
}
7.为避免在一个目录保存多个文件,影响文件读取的性能,应把文件打散到多个目录存储
public String generateFilepath(String uploadpath,String filename){ //upload
int hashcode = filename.hashCode();
int dir1 = hashcode&0xf;
int dir2 = (hashcode>>4)&0xf;
// http:// c:\\
String savepath = uploadpath + "\" + dir1 + "\" + dir2;
File file = new File(savepath);
if(!file.exists()){
file.mkdirs();
}
return savepath;
}
8.限制上传文件的类型
得到上传文件的后缀名,判断是否合法,如果不合法,则抛异常提醒用户
9.ProgressListener显示上传进度
ProgressListener progressListener = new ProgressListener() {
public void update(long pBytesRead, long pContentLength, int pItems)
{
System.out.println("到现在为止, " + pBytesRead + " 字节已上传,总大小为 "
+ pContentLength);
}
};
upload.setProgressListener(progressListener);
以KB为单位显示上传进度
long temp = -1; //temp注意设置为类变量
long ctemp = pBytesRead /1024;
if (mBytes == ctemp)
return;
temp = mBytes;
10.做出动态上传效果
实例
public class UploadServlet4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//request.setCharacterEncoding("UTF-8");这个解决不了上传文件的乱码问题
List exts = Arrays.asList("jpg","bmp"); //创建一个集合,封装限制上传文件类型数据
try{
//1.创建工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//设置缓冲文件夹路径
factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));
//2.得到解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//设置解析器的字符集
upload.setHeaderEncoding("UTF-8");
//设置单个上传文件最大容量
upload.setFileSizeMax(1024*1024);
//设置多个上传文件最大容量
upload.setSizeMax(1024*1024*5);
//设置监听器,创建一个接口,实现接口方法,从监听器中获得:上传文件的当前上传字节pBytesRead,上传文件总大小pContentLength,正在处理的上传对象pItems
upload.setProgressListener(new ProgressListener(){
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("当前处理的是" + pItems + "上传文件,文件大小是: " + pContentLength + ",当前已上传:" + pBytesRead + "字节");
}
});
//3.用解析器解析request,得到代表每一个输入项的fileitem对象
List<FileItem> list = upload.parseRequest(request);
//4.迭代集合,获取每一个fileitem的数据
for(FileItem item : list){
if(item.isFormField()){
//代表当前获取的普通输入项的数据
String inputName = item.getFieldName(); //username
String inputValue = item.getString("UTF-8"); //在获得上传数据时通过参数直接给字符集相当于下面代码
//inputValue = new String(inputValue.getBytes("iso8859-1"),"UTF-8");
System.out.println(inputName + "=" + inputValue);
}else{ //代表当前获取的item封装的是上传文件的数据
//获得上传文件的文件路径
String filename = item.getName(); //""
//判断上传文件路径为空的情况
if(filename.trim().equals("")){
continue;
}
//根据上传文件名获得文件类型,判断exts集合中是否允许该类型上传,如果不支持,抛一个自定义异常
String ext = filename.substring(filename.lastIndexOf(".")+1);
if(!exts.contains(ext)){ //集合的是否包含方法
throw new ExtException();
}
//如果支持,获得文件名
filename = filename.substring(filename.lastIndexOf("\")+1); //""
//获得上传对象的输入流读取文件输出到指定位置
InputStream in = item.getInputStream();
int len = 0;
byte buffer[] = new byte[1024];
//输出路径
String uploadpath = this.getServletContext().getRealPath("/WEB-INF/upload");
//传入文件名返回一个随即生成带ID的唯一保存文件名
String saveFilename = generateFilename(filename);
//传入输出路径和保存文件名,根据hash算法创建目录,返回一个用于将传入文件打散保存的保存路径
String savePath = generateFilepath(uploadpath, saveFilename);
//创建输出流到指定保存地址
FileOutputStream out = new FileOutputStream(savePath + "\" + saveFilename);
相关文章推荐
- 文件上传时细节的处理
- 上传文件细节处理问题
- Java+Selenium3方法篇38-AutoIt工具处理文件上传
- 上传文件的处理细节
- Asp.net 文件上传的 FileUpload FileName 和 FileUpload PostedFile.FileName的细节问题
- 上传文件细节处理问题
- 上传文件细节处理问题(包括中文乱码、限制文件大小、显示上传速度、删除临时文件,随机生成文件夹等)
- 用fileupload处理文件上传
- 文件上传细节处理
- iOS-svn工具Cornerstone上传忽略.a文件的处理方法
- apache commons fileupload 处理文件上传的两种方式(流式和非流式)
- 上传文件细节处理问题
- Servlet上传文件乱码处理(ServletFileUpload乱码处理)
- apache的开源工具common-fileupload实现文件上传和下载
- 上传文件的处理细节
- Java中关于文件上传的基本处理方法Commons-FileUpload
- iOS开发之--svn工具Cornerstone上传忽略.a文件的处理方法
- 上传文件的处理细节、文件下载
- 使用Commons-fileupload组件实现文件上传的注意细节
- java 上传包 commons-fileupload-1.2.jar处理上传文件