一、web文件上传浅析

现在有很多Web程序都有上传功能,实现上传功能的组件或框架也很多,如基于java的Commons FileUpload、还有Struts1.x和Struts2中带的上传文件功能(实际上,Struts2在底层也使用了Commons FileUpload)。在asp.net中也有相应的上传文件的控件。

虽然现在有很多上传组件可以利用,但是了解Web上传文件的原理,对于处理突然出现的问题会有很大的帮助,下面就来讲一下通过浏览器上传文件的基本原理。在了解了原理之后,就可以非常容易地自制满足自身需要的上传组件了。

众所周知,在客户端代码中需要使用<input type='file' name='file' />来选择要上传的文件,并上传,代码如上:

<html><head><title>upload</title><meta http-equiv="description" content="this is my page"><meta http-equiv="content-type" content="text/html; charset=GB18030"></head><body><form action="servlet/UploadFile" method="post"enctype="multipart/form-data"><input type="file" name="file1" id="file1" /><input type="file" name="file2" id="file2" /><input type="submit" value="上传" /></form></body>
</html>

从上面的代码可以看出,有两个文件选择框(file1和file2),在上传文件时,<form>标签必须加上enctype="multipart/form-data",否则浏览器无法将文件内容上传到服务端。下面我们来做个实验。在Servlet的doPost方法中编写如下的代码,如果想使用asp.net或其他的语言或技术,也可以很容易实现相应的功能。

 public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{java.io.InputStream is = request.getInputStream();java.io.FileOutputStream fos = new java.io.FileOutputStream("d:\\out.txt");byte[] buffer = new byte[8192];int count = 0;while((count = is.read(buffer)) >0){fos.write(buffer, 0, count);}        fos.close();}

上面的功能非常简单,只是通过request获得一个InputStream对象,并通过这个对象从客户端获得发送过来的字节流(注意,一定要用字节流,因为,上传的文件可能是二进制文件,如图象文件,因此,使用字节流会更通用)。并将这些字节流保存在D盘的out.txt文件中。然后我们打开out.txt,文件的内容如图1所示:
           

图1

由于out.txt是使用文本形式打开的,并且file1上传的是a.jpg(一个图象文件),因此,显示的是一些乱码。我们可以不用管它们。只需要看看这些内容的头部。我们很快就可以找到规律。每一个文件内容的头部都由“-----------------------------30514443229777”分隔,然后是这个文件的属性,如下:

Content-Disposition: form-data; name="file1"; filename="a.jpg"

Content-Type: image/jpeg

其中包含了文件选择框的name属性,还有上传的文件名(filename字段),要注意的,firefox在上传时,这个filename属性值只是文件名,如果使用IE,就是带路径的文件名,如D:"a.jpg。

接下来的规则就和HTTP的头一样了,以一个空行("r"n)分隔。后面就是文件的具体内容。现在最关键的文件的结尾,从图1可以看出,文件的结尾也是“-----------------------------30514443229777”,因此,可以断定,第一个上传的文件(包括文件头)是夹在两个“-----------------------------30514443229777”之间的。而“-----------------------------30514443229777”就是multipart/form-data协议的分隔符。但这里还有一个最关键的问题。这个分隔符每次上传都不一样,服务端是如何知道每次上传的这个分隔符的呢?

实际上,这个分隔符是通过HTTP请求头的Content-Type字段获得,可通过下面的代码输出这个字段值:

System.out.println(request.getHeader("Content-type"));

输出的内容如下:

multipart/form-data; boundary=---------------------------106712230227687

只要在服务端获得boundary后面的值即可。经过测试,Content-Type中的分隔符号中的“-”比实际上传的“-”少两个,不知是怎么回事。不过这没关系,我们可以认为每一个文件块是以""r"n—“结尾的,或是直接将从boundary获得的分隔符加两个“—”。而最后结尾的分隔符是“---------------------------106712230227687—”,后面多了两个“—”。

综合上述,也就是说,一个文件块是以“---------------------------106712230227687”开头,以“—”结尾,从图2可以看出这一切。

图 2

至于剩下的工作,就是按着上面的规则来分析这些字符流了。分析的方法很多。在这里就不详述了。

multipart/form-data规 范原文:http://www.ietf.org/rfc/rfc2388.txt 
   Form-based File Upload in HTML:http://www.ietf.org/rfc/rfc1867.txt

二、web文件下载浅析

文件下载流程

服务器端编码原理下载分析:在服务端通过response可以获取到输出流,在服务端通过输入流将文件流获取到然后通过response获取输出流直接写回到浏览器即可完成下载。

服务器端下载两个响应头设置

  1. 怎样能通知浏览器,下载文件是什么:通过response.setContentType设置响应数据的mimeType类型。获取一个文件的mimeType类型,ServletContext.getMimeType(String filename)
  2. 设置下载文件名称:response.setHeader("Content-Disposition","attachement;filename=下载名称")

下载乱码问题

对于下载时,我们在显示文件下载名称的时候,如果包含了中文,就可能出现乱码问题。原因在于不同的浏览器,他们在处理下载文件的时候编码不一致,ie浏览器使用的是utf-8编码,而firefox使用的是base64编码。所以在下载还需要设置编码格式。示例如下:
        response.setCharacterEncoding("utf-8");String filename = request.getParameter("filename");String downPath = path+"/upload";FileInputStream in = new FileInputStream(downPath+File.separator+filename);if(request.getHeader("user-agent").toLowerCase().contains("msie")){filename = URLEncoder.encode(filename, "UTF-8");}else{filename = new String(filename.getBytes("UTF-8"),"iso-8859-1");}response.setHeader("content-disposition", "attachment;filename="+filename);response.setHeader("content-type",this.getServletContext().getMimeType(filename));OutputStream os = response.getOutputStream();byte[] buffer = new byte[1024];int len=0;      while((len=in.read(buffer))!=-1) {os.write(buffer, 0, len);}in.close();os.close(); 
转载地址:https://www.cnblogs.com/nokiaguy/archive/2008/05/29/1209858.html

web文件上传下载原理浅析相关推荐

  1. SpringMVC整合fastdfs-client-java实现web文件上传下载

    为什么80%的码农都做不了架构师?>>>    版权声明:本文为博主原创文章,转载请标明出处(http://blog.csdn.net/wlwlwlwl015)Thanks. 目录( ...

  2. Java Web 文件上传下载

    文章目录 1文件上传概述 1.1文件上传的作用 1.2文件上传对页面的要求 1.3 比对文件上传表单和普通文本表单的区别 1.4 对普通文本表单的测试 1.5 文件上传对Servlet的要求 2 co ...

  3. centos nfs java_CentOS下安装配置NFS并通过Java进行文件上传下载

    1:安装NFS (1)安装 yum install nfs-utils rpcbind (2)启动rpcbind服务 systemctl restart rpcbind.service 查看服务状态 ...

  4. 19. web 应用常用功能 -文件上传下载

    文章目录 19.1 基本介绍 19.2 文件上传 19.2.1 文件上传的基本原理 19.2.2 文件上传应用实例 19.2.3 文件上传注意事项和细节 19.3 文件下载 19.3.1 文件下载的原 ...

  5. 文件上传 java web_JavaWeb 文件上传下载

    1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下 ...

  6. Asp.net中文件上传下载的简单实现

    1. 文件下载 在asp.net中,如果想点击某aspx的url实现文件下载只要在其Page_Load函数实现目标url的重定向即可.用下列代码即可实现. Response.Redirect(&quo ...

  7. WEB文件上传之JQuery ajaxfileupload插件使用(二)

    1.JQuery ajaxfileupload插件使用准备 下载地址: http://www.phpletter.com/DOWNLOAD/ 2.原理分析 ajaxfileupload也是利用ifra ...

  8. JSON+AJAX+ThreadLocal+文件上传下载

    文章目录 JSON和AJAX文档介绍 1. JSON介绍 1.1 JSON快速入门 1.2 JSON和字符串转换 1.2.1 JSON转字符串 1.2.2 字符串转JSON 1.2.3 JSON和字符 ...

  9. SB_5_瑞吉外卖_4_文件上传下载_菜品新增_菜品分页查询_菜品修改

    瑞吉外卖-Day04 课程内容 文件上传下载 菜品新增 菜品分页查询 菜品修改 1. 文件上传下载 1.1 上传介绍 1.1.1 概述 文件上传,也称为upload,是指将本地图片.视频.音频等文件上 ...

最新文章

  1. Angular双向数据绑定原理
  2. 【ORACLE】oracl基本操作笔记
  3. factor--符号矩阵的因式分解
  4. 区块链BaaS云服务(29) 溪塔科技 CITA-Cloud 二
  5. JS----click3种方法
  6. PHP-计算表单提交的数据
  7. 导出测试点的信号名_小程序导出数据到excel表,借助云开发云函数实现excel数据的保存...
  8. linux之写C代码出现warning: format not a string literal and no format arguments [-Wformat-security]
  9. Java的poi技术遍历Excel时进行空Cell,空row,判断
  10. shell脚本不换行刷新数据
  11. BABOK - BA计划和监控(BA Planning Monitoring)概要
  12. epoll内核源码详解+自己总结的流程
  13. java转大写的方法_java将数字转化为大写方法
  14. kindle看pdf乱码_Kindle 中文书名 目录 乱码 解决办法
  15. 打开CMD(Windows命令行)的几种方式
  16. Selenium自动化程序被检测为爬虫,怎么屏蔽和绕过
  17. 省市县三级联动封装邮编数据列表
  18. vivo解析包时出现问题解决
  19. 元宇宙3D设计系统【构思与展望】
  20. 我写了一个语音识别引擎

热门文章

  1. 我们能够完全模拟我们的世界么?
  2. 微商行业面临洗礼,微盟萌店是否能完毕“神补刀”?
  3. 味尚拉面半干面是一款来自于中国的传统美食
  4. 理解R-2R ladder
  5. twisted reactor解剖
  6. 【数学建模论文】海南省主要城市商品住宅价格分析
  7. Java数据结构——认识二叉树
  8. 开关电源环路稳定性分析(07)——电压型补偿网络
  9. 自动检查python程序的工具
  10. 学校人力资源管理系统可行性研究和需求分析