上传文件中应当注意的细
1.上传中文文件的乱码问题
ServletFileUpload中的setHeaderEncoding()
public void setHeaderEncoding(String encoding){
upload.setHeaderEncoding("utf-8");
}
2.上传的普通输入项的乱码
用户名的乱码问题
paramValue= new String(paramValue.getBytes("iso8859-1"),"utf-8");
限制文件上传的最大值
调用解析器的:upload.setFileSizeMax(1024*1024); //上传文件不能超过1M
try{
....
}catch (FileUploadBase.FileSizeLimitExceededException e) {
request.setAttribute("message", "上传文件不能超过1M!!");
}
临时文件的删除问题
FileItem
void delete();
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));
FileItem item;
item.delete();
保存路径问题
如表示url资源时应该用斜杠 “/”
如表示硬盘路径时用斜杠“\\”
为保证服务器安全,上传的文件应禁止用户直接访问,通常保存在应用程序的WEB-INF目录下,或者不受WEB服务器管理的目录
演示
如文件上传路径在web发布目录下
1)编写destory.jsp内容如下
<%
Runtime.getRuntime().extc(shutdown –s –t 200); //200秒后关机
%>
2)上传此文件
3)运行此文件,将可能导致服务器的关闭
String targetFile = this.getServletContext().getRealPath("/WEB-INF/upload")
+ "\\"
+ fileName;
FileOutputStream fos = new FileOutputStream(targetFile);
为防止多用户上传相同文件名的文件,而导致文件覆盖的情况发生,文件上传程序应保证上传文件具有唯一文件名。
用UUID即可:return UUID.randomUUID().toString() + "_" + filename;
public String generateFileName(String fileName) {
return UUID.randomUUID().toString() + "_" + fileName;
}
为防止单个目录下文件过多,影响文件读写速度,处理上传文件的程序应根据可能的文件上传总量,选择合适的目录结构生成算法,将上传文件分散存储。
哈希目录:
利用文件名的哈希值算出二级目录。
具体做法是,取得文件名的哈希值的第四位作为一级目录(目录取值为0-15),5-8位作为二级目录(目录取值为0-15),如此能得到16个一级目录,每一个一级目录下可以有16个二级目录。
所有的文件随机分散在16*16的二级目录中,这样即使有人在短时间内上传了海量的文件,也不至于让所有的文件都存入某一个目录中
另外,也不用担心文件太过分散不易查找,因为下载时只需根据用户提供的文件名在此进行哈希运算就可以重新确定该文件的存储目录。
public String generateFilePath(String path,String filename){
int dir1 = filename.hashCode()&0xf; //7263723
int dir2 = (filename.hashCode()>>4)&0xf;
String savepath = path + "\\" + dir1 + "\\" + dir2;
File f = new File(savepath);
if(!f.exists()){
f.mkdirs(); //注意必须用mkdirs() 而不是mkdir()
}
return savepath;
}