上传文件细节处理问题
一 中文乱码问题
1.上传文件的中文乱码问题
用解析器的对象去调用setHeaderEncoding方法设置就行
// (1)创建一个解析器工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// (2)得到解析器
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setHeaderEncoding("utf-8");
注:
request.setCharacterEncoding(“utf-8”);解决的是用post方法提交的参数,并且设置到的是 request.getParament(“user”)的字符编码。
2. 普通输入项的中文乱码问题
第一种:inputValue = new String(inputValue.getBytes("iso8859-1"),
"utf-8");
第二种:String inputValue = item.getString("utf-8");
注:inputVaule是:
String inputName = item.getFieldName(); // 输入项的名称
String inputValue = item.getString(); // 输入项的value值
二 防止用户不在文件上传的输入项中输入上传文件
用法是:判断获取到的是否为空,最好截取左右两边的空串
代码:
if (!fileName.trim().equals("")) {
//读取上传文件的内容并存入本地磁盘
// 得到上传的文件名
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
InputStream is = item.getInputStream();// 得到上传的输入流
// 输出到本地磁盘上
FileOutputStream fos = new FileOutputStream("c:\\"
+ fileName);
byte[] buff =new byte[1024];
int len = 0;
while ((len = is.read(buff)) > 0) {
fos.write(buff, 0, len);
}
is.close();
fos.close();
}
三 删除临时文件
临时文件出现的原因是上传的文件过大,超出了DiskFileItemFactory.setSizeThreshold方法设置的内存缓冲区的大小,Commons-fileupload组件将使用临时文件保存上传数据,因此在程序结束时,务必调用FileItem.delete方法删除临时文件。
1. 指定保存临时文件的目录
factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));
2.删除临时文件
is.close();
fos.close();
item.delete();
四 文件的存放位置:服务的安全性
为保证服务器安全,上传文件应保存在应用程序的WEB-INF目录下,或者不受WEB服务器管理的目录。
首先确定上传的文件要保存在哪个目录下 保证文件的安全性,在WEB-INF下
String savePath = this.getServletContext().getRealPath(
"WEB-INF/upload");
构建输出流对象
FileOutputStream fos = new FileOutputStream(savePath
+ "\\" + fileName);
注:在webRoot下是不受保护的
五 多个用户上传了同名的文件,这时后面的人上传的文件就会覆盖原来的文件,可以给定唯一的文件名来保证
UUID类是用来随机的生成唯一的标识符
String fileName = item.getName();
fileName = UUID.randomUUID().toString() + "_"+ fileName;
六 防止在同一个文件夹下存放的目录过多
解决:在同一个文件夹下放置的文件过多,可以根据可能的文件上传总量,选择合适的目录结构生成算法,将上传文件分散存储
1. 打散存储的方法
//产生目录结构的算法---hash目录
public String generateFilePath(String path,String fileName){
//得到一级目录名 得到的是内存的地址()哈希码
int dir1 = fileName.hashCode() & 0x0f;
//二级目录
int dir2 = fileName.hashCode()>>4 & 0x0f;
String savePath = path+"\\"+dir1+"\\"+dir2+"\\";
//如果目录不存在,创建
File f = new File(savePath);
if(!f.exists()){
f.mkdirs();//多级目录的创建
}
return savePath;
}
2.调用:
String savePath =this.getServletContext().getRealPath(
"WEB-INF/upload");
savePath = generateFilePath(savePath, fileName);
七 限制上传文件的大小
// 限制上传文件的大小 为1兆
1. 设置
upload.setFileSizeMax(1024 * 1024);
2.用异常去捕获
catch (FileUploadBase.FileSizeLimitExceededException e) {
request.setAttribute("message", "上传的文件不能超过1M");
}
八 限制上传文件的类型
1. 定义能上传哪些类型的文件
第一种:
String[] arr ={".jpg",".bmp",".avi"};
Private List fileType = Arrays.asList(arr);
第二种:
private List fileType=Arrays.asList(".jpg",".bmp",".avi");
九 显示上传进度
使用ProgressListener接口中的 Update抽象方法,系统会自动的传参数,并且在显示的时候用内部类,或者是匿名类。
1.内部类
class ProgressHandlerimplements ProgressListener{
public void update(long arg0,long arg1, int arg2) {
System.out.println("现在已经处理了"+arg0+"数据,总数据量是"+arg1+",正在处理第"+arg2+"个数据");
}
}
2.调用:upload.setProgressListener(new ProgressHandler());