您的位置:首页 > 编程语言 > Java开发

Java基础 文件的上传和下载

2017-12-15 08:14 387 查看
文件上传和下载
1.1 
文件的上传:
1.1.1            
文件上传的概述:

什么是文件上传:
文件上传:
QQ上传头像.将文件存入到网盘中...
将本地文件写到服务器上.

文件上传的三要素:
文件上传的三要素:
 表单的提交的方式必须是POST方式:
 GET方式有大小的限制的.POST方式没有大小的限制.
 表单中需要有文件上传项:
 在表单中需要有<input type=”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

步骤二:创建一个页面:

 满足文件上传的条件:

<h1>文件上传的页面</h1>

<!--

文件上传的三要素

      表单的提交的方式必须是POST方式:

           GET方式有大小的限制的.POST方式没有大小的限制.

      表单中需要有文件上传项:

           在表单中需要有<input type=”file”>.而且文件上传项必须有name的属性.

      表单的enctype属性:必须设置为multipart/form-data

 -->

<form action="${ pageContext.request.contextPath }/uploadServlet" method="post" enctype="multipart/form-data">

     文件描述:<input type="text" name="desc"/><br/>

     文件上传:<input type="file" name="upload"/><br/>

     <input type="submit" value="文件上传">

</form>

步骤三:编写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<FileItem> 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的代码:

<script type="text/javascript">

     function add(){

          // 获得div的元素:

          var div1 = document.getElementById("div1");

          // 向div1中写入内容:

          div1.innerHTML += "<div>文件上传:<input type='file' name='upload'/><input type='button' value='删除' onclick='del(this)'></div>";

     }

    

     function del(who){

          // 获得删除按钮的父节点的div.

          // var div = who.parentNode;

          // 找到div的父节点将div节点移除.

          // div.parentNode.removeChild(div);

          who.parentNode.parentNode.removeChild(who.parentNode);

     }

</script>

文件上传过程中的问题的解决:

问题:上传文件的文件名的重名的问题:

* 张三和李四都要去上传一个文件: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            
文件下载两种形式:

文件下载有两种方式:

 一种:超链接下载.

 对于下载的资料.将资源写到<a href=”资料路径”>下载</a>.

 前提:如果浏览器支持这个格式的文件.可以在浏览器中打开.如果浏览器不支持这个格式的文件.提示下载.

 二种:手动编写代码的方式进行下载.

 无论浏览器是否支持该格式的文件:提示下载.

 设置两个头和一个流:

 Content-Type:代表的是文件的MIME类型.

 Content-Dispostion:代表文件需要以下载的形式打开.

 InputStream:代表的文件的输入流.

 因为输出流是固定的:response.getOutputStream();

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

<h1>使用超链接的方式完成文件下载</h1>

<h3>文件下载</h3>

<a href="${ pageContext.request.contextPath }/download/tu1.zip">tu1.zip</a><br/>

<a href="${ pageContext.request.contextPath }/download/tu2.jpg">tu2.jpg</a><br/>
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);

          }

     }

}

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