Java基础 文件的上传和下载

文件上传和下载
1.1   文件的上传:
1.1.1              文件上传的概述 :
什么是文件上传 :
文件上传:
QQ 上传头像. 将文件存入到网盘中...
将本地文件写到服务器上.
文件上传的三要素 :
文件上传的三要素:
  表单的提交的方式必须是POST 方式:
 GET 方式有大小的限制的.POST 方式没有大小的限制.
  表单中需要有文件上传项:
  在表单中需要有”file >. 而且文件上传项必须有name 的属性.
  表单的enctype 属性: 必须设置为multipart/form-data
文件上传的原理分析 :
 没有设置enctype属性的情况:
Httpwatch抓包
=========================enctype属性为默认值的情况:没有文件中的内容.
 设置了enctype属性为multipart/form-data
 
文件上传的技术 :
JSPSmartUpload:jspSmartUpload组件是应用JSP进行 B/S 程序开发过程中经常使用的上传下载组件,它使用简单,方便。现在我又为其加上了下载中文名字的文件的支持,真个是如虎添翼,必将赢得更多开发者的青睐。
FileUpload:FileUpload 是Apache commons下面的一个子项目,用来实现 Java 环境下面的文件上传功能,与常见的SmartUpload齐名.
Servlet3.0       :提供了文件上传的功能.
Struts2                 :提供了文件上传和下载的功能.
1.1.2              文件上传的入门案例 :
步骤一 : 创建一个 web 项目 , 引入相应 jar :
 引入jar包:
 commons-fileupload-1.2.1.jar
 commons-io-1.4.jar
步骤二 : 创建一个页面 :
 满足文件上传的条件:

文件上传的页面

     文件描述:
     文件上传:
    
步骤三 : 编写 Servlet:
public class UploadServlet extends HttpServlet {
 
     public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
          /*InputStream is = request.getInputStream();
          String info = IOUtils.toString(is);
          System.out.println(info);*/
          /**
           * 使用FileUpload组件完成文件上传:
           * * 创建一个磁盘文件项工厂:
           * * 创建一个核心解析类:
           * * 使用核心解析类解析request请求.返回一个List集合.封装的一个FileItem的对象.
           * * 遍历List集合获得到表单中的每个部分(FileItem).
           *        * 判断FileItem是否是文件上传项:
           *             * 文件上传项:完成文件上传.
           *             * 普通项:获得普通项名称和值.
           */
          // 创建磁盘文件项工厂:
          DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
          // 创建核心解析类:
          ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
          // 解析request请求:
          try {
                List list = servletFileUpload.parseRequest(request);
                // 遍历集合获得到每个部分:
                for (FileItem fileItem : list) {
                      // 判断是否是文件上传项:
                      if(fileItem.isFormField()){
                           // 普通项
                           String name = fileItem.getFieldName();
                           String value = fileItem.getString();
                           System.out.println(name+"    "+value);
                      }else{
                           // 文件上传项
                           // 获得文件上传的路径:
                           String path = this.getServletContext().getRealPath("/upload");
                           // 获得文件名称:
                           String fileName = fileItem.getName();
                           // 获得文件的内容:
                           InputStream is = fileItem.getInputStream();
                           // 创建一个输出流:
                           OutputStream os = new FileOutputStream(path+"\\"+fileName);
                           // 两个流完成对接:
                           byte[] b = new byte[1024];
                           int len = 0;
                           while((len = is.read(b))!=-1){
                                 os.write(b, 0, len);
                           }
                           is.close();
                           os.close();
                      }
                }
          } catch (FileUploadException e) {
                e.printStackTrace();
          }
     }
 
     public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
 
          doGet(request, response);
     }
 
}
1.1.3              FileUpload 中的核心 API:
DiskFileItemFactory: 磁盘文件项工厂 :
构造方法:
无参数的构造方法
 带有参数的构造方法:
 参数:
 int sizeThreshold      :FileUpload组件的缓冲区大小.默认是10kb.
 File repository    :文件上传过程中产生临时文件存放的路径.
 
方法:
 设置FileUpload的组件的文件上传的缓冲区.
 设置临时文件存放的路径.
ServletFileUpload: 核心解析类 :
构造方法:
 
方法:
 是用来判断表单的enctype的属性是否是multipart/form-data.
 处理中文文件名的上传的乱码问题:
 解析request请求:返回一个List集合.List集合中封装的FileItem的对象.
 设置单个文件上传大小:
 设置表单中的所有文件上传的总大小:
 设置监听器:作用监听上传的进度.
FileItem: 文件项 .
方法:
 判断表单的元素是普通项还是文件上传项.普通项返回true.如果是文件上传项返回false.
 获得普通项的名称:
 获得普通项的值:
 getString();
 getString(String encoding); ----用来解决普通项的中文乱码的问题.
 获得文件上传项的文件的名称.
 获得文件上传项的文件的内容.
 删除文件上传中的临时文件的.
通过JS控制多文件的上传:
使用JS添加节点移除节点:
JS的代码:
文件上传过程中的问题的解决:
问题:上传文件的文件名的重名的问题:
* 张三和李四都要去上传一个文件:aaa.txt
* 张三的aaa.txt:hello world...
* 李四的aaa.txt:我是李四...
***** 后上传的文件就会将先上传的问题覆盖了.
 
* 使用唯一文件名:(使用随机的字符串作为文件名.)
* 在Java中如何生存一个不重复的随机的字符串?
* UUID     :UUID.randomUUID();
 
* 抽取一个获得唯一文件名工具类:
public class UUIDUtils {
 
     /**
      * 生成唯一文件名的方法:
      * @param fileName:真实文件名.
      * @return
      */
     public static String getUUIDFileName(String fileName){
          return UUID.randomUUID().toString().replace("-", "")+"_"+fileName;
     }
}
1.2   文件下载:
1.2.1              文件下载的概述 :
什么是文件下载 :
文件下载   :将服务器上文件下载到本地计算机.
 从网盘中下载文件.
 下载音乐,电影.
1.2.2              文件下载两种形式 :
文件下载有两种方式:
 一种:超链接下载.
 对于下载的资料.将资源写到下载.
 前提:如果浏览器支持这个格式的文件.可以在浏览器中打开.如果浏览器不支持这个格式的文件.提示下载.
 二种:手动编写代码的方式进行下载.
 无论浏览器是否支持该格式的文件:提示下载.
 设置两个头和一个流:
 Content-Type:代表的是文件的MIME类型.
 Content-Dispostion:代表文件需要以下载的形式打开.
 InputStream:代表的文件的输入流.
 因为输出流是固定的:response.getOutputStream();
超链接的方式完成文件下载 :

使用超链接的方式完成文件下载

文件下载

1.2.3              文件下载的入门案例 :
手动编码的方式完成文件的下载:
public class DownloadServlet extends HttpServlet {
 
     public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
          /**
           * 1.接收文件名.
           * 2.完成文件的下载:
           * * 获得download路径下的该文件:获得download路径的磁盘绝对路径.
           * * 设置两个头和一个流:完成文件下载.
           *        * Content-Type    :MIME类型.
           *        * Content-Dispostion :
           *        * InputStream:
           */
          // 1.接收文件名:
          String filename = request.getParameter("filename");
          // 2.获得download的磁盘绝对路径.
          String path = this.getServletContext().getRealPath("/download");
          // 3.设置两个头和一个流:
          // 动态获得文件的MIME的类型:
          String mimeType = this.getServletContext().getMimeType(filename);
          response.setContentType(mimeType);
          // 设置Content-Dispostion:
          response.setHeader("Content-Disposition", "attachement;filename="+filename);
          // 设置文件的输入流InputStream:
          InputStream is = new FileInputStream(path+"\\"+filename);
          // 获得一个向浏览器输出的一个输出流:
          OutputStream os = response.getOutputStream();
          byte[] b = new byte[1024];
          int len = 0;
          while((len = is.read(b))!=-1){
                os.write(b, 0, len);
          }
          is.close();
     }
 
     public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
 
          doGet(request, response);
     }
 
}
对于中文文件名的处理办法 :
          // 如果是中文的文件:不同的浏览器是有不同的编码的格式的:
          // IE浏览器对中文文件使用的URL编码.Firefox浏览器对中文文件采用的是Base64编码.

          // 判断不同的浏览器采用不同的编码的格式:
           // User-Agent:包含了客户端的浏览器的信息.
          String agent = request.getHeader("User-Agent");
          // System.out.println(agent);
          if(agent.contains("Firefox")){
                // 火狐浏览器:
                filename = base64EncodeFileName(filename);
          }else{
                // IE浏览器:
                filename = URLEncoder.encode(filename, "UTF-8");
          }
          response.setHeader("Content-Disposition", "attachment;filename="+filename);
          // 提供文件的输入流:
          InputStream is = new FileInputStream(path);
          // 提供输出流:
          OutputStream os = response.getOutputStream();
          // 两个流对接:
          byte[] b = new byte[1024];
          int len = 0;
          while((len = is.read(b))!=-1){
                os.write(b, 0, len);
          }
          is.close();
     }
 
     public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
 
          doGet(request, response);
     }
 
     /**
      * Base64对文件名进行编码:
      * @param fileName
      * @return
      */
     public String base64EncodeFileName(String fileName) {
          BASE64Encoder base64Encoder = new BASE64Encoder();
          try {
                return "=?UTF-8?B?"
                           + new String(base64Encoder.encode(fileName
                                      .getBytes("UTF-8"))) + "?=";
          } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
          }
     }
}
 

你可能感兴趣的:(Java基础)