文章目录
文件上传概述文件上传的原理分析代码实现文件上传的APIJS控制多文件上传文件上传中兼容浏览器的问题文件上传同一个目录下文件同名的问题文件上传同一个目录下文件过多的问题
文件上传概述
将本地的文件通过流写入到服务器的过程。
QQ上传照片招聘网站上传简历
文件上传技术
JSPSmartUpload:应用在JSP上的文件上传和下载的组件。FileUpload:应用在java环境上的文件上传的功能。Servlet3.0:提供文件上传的功能。Struts2:提供文件上传的功能。
文件上传的要素:
表单提交的方式需要时POST表单中需要有文件上传的组件,表单有< input type=“file” >元素,需要有name属性和值。表单< enctype=“multipart/form-data” >
文件上传的原理分析
代码实现
引入jar包 编写页面 编写文件上传的Servlet
public class UploadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request
, HttpServletResponse response
) throws ServletException
, IOException
{
try {
DiskFileItemFactory diskFileItemFactory
= new DiskFileItemFactory();
ServletFileUpload fileUpload
= new ServletFileUpload(diskFileItemFactory
);
List
<FileItem> list
= fileUpload
.parseRequest(request
);
for (FileItem fileItem
: list
) {
if(fileItem
.isFormField()) {
String name
= fileItem
.getFieldName();
String value
= fileItem
.getString("UTF-8");
System
.out
.println(name
+" "+value
);
}else {
String filename
= fileItem
.getName();
InputStream is
= fileItem
.getInputStream();
String realPath
= getServletContext().getRealPath("/upload");
OutputStream os
= new FileOutputStream(realPath
+"/"+filename
);
int len
= 0;
byte[] b
= new byte[1024];
while((len
= is
.read(b
)) != -1) {
os
.write(b
,0,len
);
}
is
.close();
os
.close();
}
}
} catch (FileUploadException e
) {
e
.printStackTrace();
}
}
protected void doPost(HttpServletRequest request
, HttpServletResponse response
) throws ServletException
, IOException
{
doGet(request
, response
);
}
}
文件上传的API
DiskFileItemFactory磁盘文件项工厂 ServletFileUpload核心解析类
构造方法:
ServletFileUpload();ServletFileUpload(FileItemFactory fileItemFactory); 方法:
isMultipartContext():判断表单的enctype属性是否正确;parseRequest():解析Request对象,返回一个List集合(每个部分的对象FileItem);setFileSizeMax():设置单个文件上传大小;setSizeMax():设置文件上传总大小;setProgressLstener():设置监听文件上传进度;setHeaderEncoding():设置中文文件名的上传乱码问题 FileItem文件项
isFormFiled():判断表单是普通项还是文件上传项,如果为true则代表为普通项;getFileName():获得普通项名称;getString():获得普通项的值;getName():获得上传项的名称;getInputStream():获得上传的文件内容;getSize():获得文件上传的文件大小;delete():删除文件上传过程中的临时文件;
JS控制多文件上传
<%@ page language
="java" contentType
="text/html; charset=UTF-8"
pageEncoding
="UTF-8"%>
<!DOCTYPE html
>
<html>
<head>
<meta charset
="UTF-8">
<title>Insert title here
</title
>
<script>
function
add(){
var div1Element
= document
.getElementById("div1");
div1Element
.innerHTML
+= "<div><input type='file' name='upload'><input type='button' value='删除' οnclick='del(this)'></div>";
}
function
del(who
){
var divv
= who
.parentNode
;
divv
.parentNode
.removeChild(divv
);
}
</script
>
</head
>
<body>
<h1>多文件上传
</h1
>
<form action
=" ${pageContext.request.contextPath }/UploadServlet " method
="post" enctype
="multipart/form-data">
<input type
="button" value
="添加" onclick
="add()">
<input type
="submit" value
="上传">
<div id
="div1"> </div
> <br
/>
</form
>
</body
>
</html
>
文件上传中兼容浏览器的问题
IE老版本的浏览器会出现文件名获取错误的问题,因为获取文件名称的时候会带有路径。edge也有此问题。 解决代码:
String filename
= fileItem
.getName();
int idx
= filename
.lastIndexOf("\\");
if(idx
!= -1) {
filename
= filename
.substring(idx
+1);
}
文件上传同一个目录下文件同名的问题
使用唯一文件名进行解决
编写工具类
package com
.itheima
.utils
;
import java
.util
.UUID
;
public class UploadUtils {
public static String
getUuidFileName(String fileName
) {
int index
= fileName
.lastIndexOf(".");
String extetions
= fileName
.substring(index
);
return UUID
.randomUUID().toString()+extetions
;
}
}
引入工具类
String uuidFileName
= UploadUtils
.getUuidFileName(filename
);
文件上传同一个目录下文件过多的问题
目录下文件过多,打开会卡顿,且影响读写操作。 解题思路:目录分离
按时间分离:按月、周、天等按用户分离:按张三、李四按个数分离:一个目录存放3000个文件按目录分离算法:按某种特定算法进行分离
上传一个文件,得到唯一文件名,获取hashcode值(32位int类型的值),让hashcode的值&0xf,得出值为一级目录;让hashcode右移4位&0xf,得出这个值位二级目录,以此类推。 工具类中编写方法:
public static String
getRealPath(String uuidFileName
) {
int code1
= uuidFileName
.hashCode();
int d1
= code1
& 0xf;
int code2
= code1
>>> 4;
int d2
= code2
& 0xf;
return "/"+d1
+"/"+d2
;
}
应用:
String path
= UploadUtils
.getRealPath(uuidFileName
);
String newPath
= realPath
+path
;
File file
= new File(newPath
);
if(!file
.exists()) {
file
.mkdir();
}