上传文件细节处理
1、解决上传文件的乱码
upload.setHeaderEncoding("UTF-8");
request.getParameter(name);且提交方式为post时,当出现中文乱码可以用request.setCharacterEncoding("UTF-8");处理
2、普通输入项的乱码问题
(1)手工方式:inputValue=new String(inputValue.getBytes("ISO8859-1"),"UTF-8");
(2)String inputValue=item.getString("UTF-8");
3、防止用户不在文件上传的输入项中输入上传文件
if(!filename.trim().equals("")){
//先截掉得到的字符传左右两边的空格,再判断是不是空串
}
4、临时文件的删除问题
//指定临时文件保存的目录----在WebRoot下创建一个临时文件夹temp保存临时文件
factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));
//关闭流
is.close();
fos.close();
item.delete();//上传结束后删除临时文件 ---一定要放在输入输出流关闭后再删除,否则系统会阻止删除
5、上传文件的保存位置:服务安全性
WEB-INF文件夹下的子文件夹中或者不受服务器管理的目录
6、多个用户上传了同名的文件,这时后面的人上传的文件就会覆盖原来的文件
唯一的文件名——解决办法UUID.randomUUID().toString()
UUID生成唯一的标示符
filename=UUID.randomUUID().toString()+"_"+filename;//随机生成唯一的标识符,并通过下划线与原来的文件名连接
7、在同一个文件夹下放置的文件个数过多的,就会造成打开文件太慢,影响读和写。
public String generateFilePath(String path,String filename){
//该方法的参数在什么样的目录下创建子目录,文件名是什么
//产生目录结构的算法:hash目录
int dir1=filename.hashCode() & 0x0f;//得到的哈希码与16进制的数相与,把这个值当成是一个一级目录名 最多有16个
int dir2=filename.hashCode()>>4 & 0x0f;//向右移动四位,再去相与,二级目录名 最多有16个
String savePath=path+"\\"+dir1+"\\"+dir2;
File f=new File(savePath);//构建文件对象
if(!f.exists()){//判断该目录是否存在,如果不存在,创建该目录
f.mkdirs();//创建多级目录
}
return savePath;
}
//在upload目录下建多级的子目录
savePath=generateFilePath(savePath,filename);
factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));//创建临时保存的目录
8、限制上传文件的大小
upload.setFileSizeMax(1024*1024);//上传的文件不能超过1M
限制所有文件的总得大小——upload.setSizeMax();
如果文件大小超过所设置的最大限度会抛异常
catch(FileUploadBase.FileSizeLimitExceededException e){
request.setAttribute("message", "文件过大,上传失败");
}
9、限制上传文件的类型
先看能上传哪些类型的文件
方法一:
String[] arr={".jpg",".bmp",".avi"};
private List fileType=Arrays.asList(arr);
方法二:
private List fileType=Arrays.asList(".jpg",".bmp",".avi");//这个方法是变长的
String ext=filename.substring(filename.lastIndexOf("."));//从点后面截取字串
if(!fileType.contains(ext)){
request.setAttribute("message", "文件类型只能是jpg、bmp和avi");
request.getRequestDispatcher("/Message.jsp").forward(request, response);
return;
}
10、显示上传的进度
ProgressListener接口 update()方法,系统会自动传参数
写出方法:
public void update(long arg0, long arg1, int arg2) {
//解析器会在解析时不停地调用此方法,直到上传完成
System.out.println("现在已经处理了"+arg0+"数据,总数据量是"+arg1+",正在处理第"+arg2+"个数据");
}
调用方法
upload.setProgressListener(new ProgressHandler());