目录
扫描二维码关注公众号,回复: 15290091 查看本文章![]()
一、文件上传
1.文件上传的概述
1.1 什么是文件上传
- 文件上传:将本地的文件通过流写入到服务器的过程。
1.2 为什么要学习文件上传
实际开发中有很多应用:
- QQ空间上传图片
- 招聘网站上传简历
1.3 文件上传的技术
- JSPSmartUpload :应用在JSP上的文件上传和下载的组件。
- FileUpload :应用在Java环境上的文件上传的功能。
- Servlet3.0 :提供文件上传的功能
- Struts2 :提供文件上传的功能
1.4 文件上传的要素
文件上传的三个要素:
- 表单的提交的方式需要是POST
- 表单中需要有<input type=”file”>元素,需要有name属性和值。
- 表单enctype=”multipart/form-data”
2.文件上传的原理分析
2.1 抓包分析
- 没有设置enctype属性
POST /web06/jsp/upload.jsp HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
X-HttpWatch-RID: 22006-10011
Referer: http://localhost:8080/web06/jsp/upload.jsp
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 53
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=D51DCB996556C94861B2C72C4D978010
info=info&upload=C%3A%5CUsers%5Cjt%5CDesktop%5Caa.txt
***** 注意:没有文件上传中的文件的具体的内容。
- 设置enctype属性
POST /web06/jsp/upload.jsp HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
X-HttpWatch-RID: 22006-10026
Referer: http://localhost:8080/web06/jsp/upload.jsp
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7e139d10110a64
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 322
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=D51DCB996556C94861B2C72C4D978010
-----------------------------7e139d10110a64
Content-Disposition: form-data; name="info"
aaa
-----------------------------7e139d10110a64
Content-Disposition: form-data; name="upload"; filename="C:\Users\jt\Desktop\aa.txt"
Content-Type: text/plain
hello world!!!
-----------------------------7e139d10110a64--
2.2文件上传的原理分析
3.文件上传的入门
3.1代码实现
- 第一步:引入文件上传的相关的jar包
- 第二步:编写文件上传的页面
- 编写文件上传的Servlet
3.2文件上传的API
3.2.1 DiskFileItemFactory:磁盘文件项工厂
- 构造方法:
①DiskFileItemFactory()
②DiskFileItemFactory(int sizeThreshold,File repostory):
sizeThreshold :设置文件上传的缓冲区的大小,默认值为10kb。
repository :设置文件上传过程中产生临时文件存放的路径。
- 方法:
setSizeThreshold() :设置缓冲区的大小
setRepository() :设置临时文件存放的路径
3.2.2 API的使用的代码
3.3.3 ServletFileUpload:核心解析类
- 构造方法:
ServeltFileUpload(FileItemFactory fileItemFactory);
- 方法:
■是用来判断表单的enctype属性是否正确。
■解析Request对象,返回一个List集合(每个部分的对象FileItem)
■设置当个文件的大小
■设置上传的文件的总大小
■设置中文文件名上传的乱码的问题。
■设置监听文件上传的进度
3.3.4 FileItem类的常用方法
1.boolean isFormField()。isFormField方法用来判断FileItem对象里面封装的数据是一个普通文本表单字段,还是一个文件表单字段。如果是普通文本表单字段,返回一个true否则返回一个false。因此可以用该方法判断是否是普通表单域还是文件上传表单域。
2.String getName()。getName方法用来获得文件上传字段中的文件名。
3.String getFieldName()。getFieldName方法用来返回表单标签的name属性的值。
4.void write(File file)。write方法将FileItem对象中的内容保存到某个指定的文件中。如果FileItem对象中的内容是保存在某个临时文件中,该方法完成后,临时文件可以会被删除。该方法也可以将普通表单字段保存在一个文件中,但最主要的用途是把上传的文件内容保存在本地文件系统中。
5.String getString()。getString()方法将FileItem对象中保存的数据流内容以一个字符串返回。它有两个重载形式。public Java.lang.String getString()和public java.lang.String getString(java.lang.String encodeing) throws java.io.UnsupportedEncodingException。前者使用缺省的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码。如果在读取普通表单字段元素的内容时,出现了乱码现象,可以调用第二个方法,并传入 正确的字符集编码名称。
6.String getContentType()。此方法用来获得上传文件的类型,即标段字段元素描述头属性“content-type”的值,如image/jpeg。如果FileItem对象对应的是普通的表单字段,将返回null。
7.boolean isInMemory()。判断FileItem对象封装的数据是保存在内存中还是硬盘中。
8.void delete()。此方法用来清空FileItem对象中封装的主体内容,如果内容是被保存在临时文件中,该方法会把临时文件删除。
9.InputStream getInputStream()。以流的形式返回上传文件的主体内容。
10.long getSize()。返回上传文件的大小。
4.JS控制多文件上传
4.1案例需求描述
4.2案例代码实现
5.文件上传兼容浏览器问题及解决
5.1 问题描述
如果使用IE老版本的浏览器出现一个文件名称获取错误问题。IE老版本获取文件名称的时候,会带有路径。
5.2 问题解决
6.文件上传同一个目录下文件同名的问题及解决
6.1 问题描述
张三向服务器上传了一个文件aa.txt内容是hello world。李四向服务器上传了一个文件aa.txt内容hello Java。后上传的文件将先上传的文件覆盖了。
6.2 问题解决
使用唯一文件名进行解决。
7.文件上传同一个目录下存放文件过多的问题及解决
7.1 问题描述
现在所有的用户都上传文件,如果网站访问量比较大,如果都上传到同一个目录下,在同一个目录下存放的文件太多了,也会对程序有影响(其实打开该目录的时候,都会很卡,更别说读写操作)。
7.2 文件解决
- 目录分离:
按时间分离 :按月、周、天、小时。
按用户分离 :按张三、李四。
按个数分离 :一个目录下存放3000个文件。
按目录分离算法 :按照某种特定算法进行分离:
①上传一个文件,得到一个唯一的文件名。
②唯一文件名获取其hashCode值。-----int类型的值(32位)
③让hashCode的值 & 0xf;-----得出的这个值作为一级目录。
④让hashCode右移4位 & 0xf;----得出的这个值作为二级目录。
⑤以此类推。
- 分析算法: