文件上传

匿名 (未验证) 提交于 2019-12-03 00:22:01

1.文件上传是什么

2.文件上传步骤


1.在用户页面中添加上传输入项(客户端页面操作)
<input type="file" name="filex">




2.在服务器端编写文件上传程序


3.上传组件(Apache commons-fileupload)使用过程

(1)创建DiskFileItemFactory对象,设置缓冲区大小和临时文件目录

public DiskFileItemFactory(int sizeThreshold,java.io.File repository)  //构造工厂时,指定内存缓冲区大小和临时文件存放位置 public void setSizeThreshold(int sizeThreshold) //设置内存缓冲区大小,默认10k public void setRepository(java.io.File repository) //设置临时文件存放位置,默认 System.getProperty("java.io.tmpdir") *内存缓存区:上传文件时,上传文件的内容优先保存在内存缓冲区中,当 *上传文临时大小超过缓冲区大小,就会在服务器端产生临时文件 *临时文件存放位置:保存超过了内存缓冲区大小上传文件而产生临时文件 *产生临时文件可以通过FileItem的delete方法删除 

(2).使用DiskFileItemFactory对象创建ServletFileUpload对象,并设置上传文件的大小限制.
(3).调用ServletFileUpload.parseRequest方法解析request对象,得到一个保存了所有上传FileItem的list集合

ServeltFIleUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中.常用的方法有: //判断上传表单是否为multipart/form-data类型 boolean isMutipartContent(HttpServletRequest request) //解析request对象,并把表单中的每一个输入项包装成fileItem对象,并返回一个保存了所有FileItem的list集合. List parseRequest(HttpServletRequest request) //设置单个上传文件的最大值 setFileSizeMax(long fileSizeMax) //设置上传文件总量的最大值 setSizeMax(long sizeMax) //解决上传文件名乱码问题 setHeadEncoding(java.lang.String encoding) //实时监听文件上传状态 setProgressListener(ProgressListener pListener) 

(4).对List进行迭代,每迭代一个FileItem对象,调用其isFormField方法判断是否上传文件.


(5).如果是文件上传就通过流获取上传的数据保存到服务器中.

boolean idFormField()判断FileItem是一个文件上传对象还是普通字段项: String getFieldName() 获得普通表单对象的name属性 String getString(String encoding)获得普通表单对象的value属性,可以用encoding进行编码设置 文件上传项: String getName()获得上传文件的文件名(有些浏览器会携带客户端路径) InputStream getInputStream()获得上传文件的输入流 delete() 在关闭FileItem输入流后,删除临时文件 
//ServletFileUpload类提供了如下方法,监听文件上传时的进度信息: pulbic void setProgressListener(ProgressListener pListener) //设置监听器,文件上传程序会自动执行,监听器中update方法 public void update(long pBytesRead,long pContentLength,int pItems) //在方法中可以获得文件总大小,已经上传大小和上传第几个元素 能否根据上面三个参数计算:剩余大小、传输速度、已用时间、剩余时间 (1).已用时间 = 当前时间 -开始时间 (2).速度 = 已经上传大小/已用时间 (3).剩余时间 = 总大小 - 已经上传大小 (4).剩余时间 = 剩余大小/速度 

1.文件保存位置


2.防止上传的文件重名覆盖

filename = UUID.randomUUID().toString()+"_"+filename;
3.防止同一个目录下上传文件过多





public static String generateRandomDir(String uui获dFileName){ //获得唯一文件名的hashcode int hashcode = uuidFileName.hashCode(); //获得一级目录 int d1 = hashcode & 0xf; //获得二级目录 int d2 = (hashcode >>> 4)&0xf; return "/"+ d2 + "/"+ d1;//共有256目录 } 

4.文件上传代码

1.创建一个UploadServlet类 try {     response.setCharacterEncoding("utf-8");     response.setContentType("text/html;charset=utf-8");      //1.创建文件上传工厂     DiskFileItemFactory factory = new DiskFileItemFactory(100, new File(this.getServletContext().getRealPath("WEB-INF/temp")));      //2.创建文件上传的核心类     ServletFileUpload fileUpload = new ServletFileUpload(factory);     //--判断当前文件上传的表单是否满足enctype=multipart/form-data     if(!fileUpload.isMultipartContent(request)){         throw new RuntimeException("请使用正确的文件上传表单上传数据!");     }     //--设置文件名解析时采用的编码     fileUpload.setHeaderEncoding("utf-8");     //--单个文件不能超过1MB     fileUpload.setFileSizeMax(1024 * 1024);     //--总大小不能超过10MB     fileUpload.setSizeMax(10 * 1024 * 1024);     //--设置上传文件的监听     fileUpload.setProgressListener(new ProgressListener(){         long begin = System.currentTimeMillis();         public void update(long pBytesRead, long pContentLength,int pItems) {     System.out.print("正在读取第"+pItems+"个上传项。。");         System.out.print("共"+pContentLength+"字节。。");         System.out.print("已经读取了"+pBytesRead+"字节。。");          long leftBytes = pContentLength - pBytesRead;         System.out.print("剩余"+leftBytes+"字节。。");          long now = System.currentTimeMillis();         long usetime = (now - begin)/1000 ;         System.out.print("已经用时" + usetime+"秒。。");          long speed = usetime == 0 ? 0 : pBytesRead / usetime / 1024;         System.out.print("上传速度" + speed+"KB/s。。");          double per = Math.round(pBytesRead * 10000.0 / pContentLength)/100.0;         System.out.println("上传百分比" + per + "%。。");          long lefttime = speed == 0 ? 0 : leftBytes /1024 / speed;         System.out.println("大致剩余时间"+lefttime+"秒");          request.getSession().setAttribute("progress", per);         }          });      //--解析request得到FileItem的集合     List<FileItem> items = fileUpload.parseRequest(request);      //--遍历每个item分别做处理     for(FileItem item : items){         if(item.isFormField()){             //普通字段项             String name = item.getFieldName();             String value = item.getString("utf-8");             System.out.println(name+"~"+value);         }else{             //文件上传项             String fname = item.getName();             //--处理ie文件名bug             if(fname.contains("\\")){                 fname = fname.substring(fname.lastIndexOf("\\")+1);             }              //--处理文件名 使其不会重复             String savename = UUID.randomUUID().toString()+"_"+fname;              //--文件分目录处理             //----获取文件名的hash 转换为16进制字符串表现形式 由于文件名随机 所以 hash值也是散列的             String hash = Integer.toHexString(savename.hashCode());              //----如果hash不足8位则在前面拼接足够8位的0             while(hash.length()<8){                 hash += "0";             }             //----遍历hash值字符串的每一个字符作为一级目录拼接             String savepath = "/WEB-INF/upload/";             for(int i = 0;i<hash.length();i++){                 savepath += (hash.charAt(i)+"/");             }             //----创建出该目录             new File(this.getServletContext().getRealPath(savepath)).mkdirs();              //----得到输入流             InputStream in = item.getInputStream();              //----得到输出流 路径就是上面 hash拼接出的路径+文件名             OutputStream out = new FileOutputStream(this.getServletContext().getRealPath(savepath + "/" +savename));              //----输出数据到文件             byte []  data = new byte[1024];             int n = -1;             while((n = in.read(data))!=-1){                 out.write(data,0,n);             }              //----关闭流             in.close();             out.close();              //----删除缓存文件             item.delete();         }     }      } catch (FileSizeLimitExceededException e) {         response.getWriter().write("文件大小超过限制!!");     } catch (Exception e) {         throw new RuntimeException(e);     } 
文章来源: 文件上传
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!