WEB中的上传文件02

本文详细探讨了在处理中文文件上传时遇到的乱码问题,并提供了相应的解决方案,包括设置请求头编码、手动转码、使用FileItem类获取正确编码的内容、判断文件名是否为空、临时文件的删除策略、保存路径的正确使用、防止文件覆盖的方法以及限制文件大小等。同时,介绍了如何通过哈希目录技术合理分布文件存储,避免文件过多影响读写速度,以及如何生成唯一文件名以确保安全性。
摘要由CSDN通过智能技术生成

三、上传文件中应当注意的细节

解决中文乱码问题

1、 上传中文文件的乱码问题

ServletFileUpload中的setHeaderEncoding()

 
public void setHeaderEncoding(String encoding)

Specifies the character encoding to be used when readingthe headers of individual part. When not specified, or null, the request encoding is used. If that is alsonot specified, or null, theplatform default encoding is used.

Parameters:

encoding - The encoding used to read part headers.


upload.setHeaderEncoding("utf-8");

 

2、 上传的普通输入项的乱码

 

l            手工转码

用户名的乱码问题

paramValue= newString(paramValue.getBytes("iso8859-1"),"utf-8");

 

l            利用FileItem类的getString(String encoding)

 

String getString(String encoding)

                 throws UnsupportedEncodingException

Returnsthe contents of the file item as a String, using the specified encoding. Thismethod uses get()to retrieve the contents of the item.


解决没有指定文件名的问题

判断获取的文件名是否为空

临时文件的删除问题

FileItem

void delete()

Deletesthe underlying storage for a file item, including deleting any associatedtemporary disk file. Although this storage will be deleted automatically whenthe FileItem instance is garbage collected, this method can be used to ensurethat this is done at an earlier time, thus preserving system resources.

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;

       }

 

限制文件上传的最大值

调用解析器的:upload.setFileSizeMax(1024*1024);  //上传文件不能超过1M

 

如果超出大小,需要给用户友好提示:

try{

       ....

}catch (FileUploadBase.FileSizeLimitExceededException e) {

       request.setAttribute("message", "上传文件不能超过1M!!");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值