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:磁盘文件项工厂:
构造方法:
![](http://note.youdao.com/yws/res/3644/044E593E711546D0831DB93665D6FBB7)
无参数的构造方法
![](http://note.youdao.com/yws/res/3643/ABCD077E09A04992A69FF387708F13CA)
带有参数的构造方法:
参数:
int sizeThreshold :FileUpload组件的缓冲区大小.默认是10kb.
File repository :文件上传过程中产生临时文件存放的路径.
方法:
![](http://note.youdao.com/yws/res/3634/003C548812F44A98B092223F6D9B2D09)
设置FileUpload的组件的文件上传的缓冲区.
![](http://note.youdao.com/yws/res/3631/BB3ECCB6F0754147A2AFBFCAA15ECC64)
设置临时文件存放的路径.
ServletFileUpload:核心解析类:
构造方法:
![](http://note.youdao.com/yws/res/3633/F64EECF9E06E40A58CF09163C549A30A)
方法:
![](http://note.youdao.com/yws/res/3640/2E22F41D46914B33954BC17CA80C456B)
是用来判断表单的enctype的属性是否是multipart/form-data.
![](http://note.youdao.com/yws/res/3635/CBDBC4A314114BE4AF1F8EC9CC0C553A)
处理中文文件名的上传的乱码问题:
![](http://note.youdao.com/yws/res/3636/271497B55BE94CEC8F628D3153631FEE)
解析request请求:返回一个List集合.List集合中封装的FileItem的对象.
![](http://note.youdao.com/yws/res/3639/E53D4219F46F40A085310F231A8260A0)
设置单个文件上传大小:
![](http://note.youdao.com/yws/res/3632/219403F6D325456C804F7F340DBFFC2E)
设置表单中的所有文件上传的总大小:
![](http://note.youdao.com/yws/res/3642/F8D162A5EEEB4E719FEC950FCDDD7474)
设置监听器:作用监听上传的进度.
FileItem:文件项.
方法:
![](http://note.youdao.com/yws/res/3645/066F8906E482482CB9D325C226D560ED)
判断表单的元素是普通项还是文件上传项.普通项返回true.如果是文件上传项返回false.
![](http://note.youdao.com/yws/res/3637/C7DF1219D69F4161BAE7F4C4AD0F8ECD)
获得普通项的名称:
![](http://note.youdao.com/yws/res/3638/6D51DD6FF7F34A6AABC957E4B42D76F9)
获得普通项的值:
getString();
getString(String encoding); ----用来解决普通项的中文乱码的问题.
![](http://note.youdao.com/yws/res/3630/57F7D028AD3642F8BE3898AF53EAF36E)
获得文件上传项的文件的名称.
![](http://note.youdao.com/yws/res/3641/C1165AB5E5C44BC5A2CD45035D24D9D1)
获得文件上传项的文件的内容.
![](http://note.youdao.com/yws/res/3646/9D5D25C1FE1D49C0B5CB86EA4CFB6B37)
删除文件上传中的临时文件的.
通过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编码.
![](http://note.youdao.com/yws/res/3677/78A9238E01964432ACEFB759130F2D4D)
// 判断不同的浏览器采用不同的编码的格式:
// 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);
}
}
}
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);
}
}
}
相关文章推荐
- Java基础——Servlet(八)文件上传下载
- Java基础——Servlet(八)文件上传下载
- Java基础——Servlet(八)文件上传下载
- Java基础——Servlet(八)文件上传下载
- 自己写的一个JSP上传文件和下载文件的JavaBean 自己写的一个JSP上传文件和下载文件的JavaBean
- jaVA使用FTP上传下载文件的问题
- JSP上传文件和下载文件的JavaBean
- Java文件上传下载 源码
- java中的文件上传及下载组件介绍
- 文件上传下载代码 java
- JAVA文件上传下载开源框架
- JAVA 文件上传与下载
- java做的比较完善的FTP连接上传下载文件【转】
- 自己写的一个JSP上传文件和下载文件的JavaBean
- JAVA实现FTP文件上传下载文件
- jaVA使用FTP上传下载文件的问题
- 自己写的一个JSP上传文件和下载文件的JavaBean
- 文件上传下载:通过java方法把附件保存到clob字段中
- JAVA基础:用Java实现HTTP文件队列下载
- 深入分析java中webwork中的文件上传机制-Java基础-Java-编程开发