您的位置:首页 > 其它

上传文件—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);

   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: