javaWeb系列之十七(上传下载)



1、文件的上传

(1)什么是上传:把客户端的文件 上传 到服务器上 。比如云盘

(2)实现上传:servlet里面没有提供上传的技术。就需要使用第三方组件,实现上传

(3)实现上传的技术:

jspSmartUpload:适于嵌入执行上传下载操作的JSP文件中

针对jsp+javabean模式的,模型一

fileUpload:mvc的开发模式,模型二

FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下面的文件上传功能

组件FileUpload依赖于Commons IO组件

实现上传使用的第三方的技术,首先需要导入jar包

(4)如何实现上传(要求):

第一个要求:有表单,但是method必须是post

第二个要求:必须要有文件输入项,在文件输入项里面必须要name属性 <input type="file" name="file"/>

第三个要求:在表单里面 enctype :multipart/form-data

enctype默认值:application/x-www-form-urlencoded

(5)文件上传的实现过程(画图)

(6)使用代码实现文件的上传

导入fileupload的jar包

使用到类 DiskFileItemFactory:磁盘文件项工厂

ServletFileUpload:核心上传类

FileItem:文件项

步骤(固定)

1、创建磁盘文件项工厂  new  DiskFileItemFactory()

2、创建核心的上传类    new ServletFileUpload(FileItemFactory fileItemFactory)

3、使用核心上传类解析request对象  parseRequest(javax.servlet.http.HttpServletRequest request)

返回list集合 泛型 FileItem

4、遍历list集合

5、判断FileItem是普通项还是文件上传项

如果是一个普通项,得到普通项的名称和值

如果是文件上传项,实现文件上传的代码

(7)核心api的使用

DiskFileItemFactory:磁盘文件项工厂

构造方法

DiskFileItemFactory()

有两个方法设置

setSizeThreshold(int sizeThreshold)

setRepository(java.io.File repository)

DiskFileItemFactory(int sizeThreshold, java.io.File repository)

第一个参数:缓冲区的大小 10k ;

第二个参数:临时文件存储路径,上传的文件大小超过缓冲区的大小产生临时文件

ServletFileUpload:核心上传类

构造方法 ServletFileUpload(FileItemFactory fileItemFactory)

解析request对象:parseRequest(javax.servlet.http.HttpServletRequest request)

返回list集合,泛型FileItem

设置文件名称有中文,设置编码:setHeaderEncoding(java.lang.String encoding)

设置单个文件上传的大小:setFileSizeMax(long fileSizeMax)

设置所有文件上传的总的大小:setSizeMax(long sizeMax)

FileItem接口:文件项

isFormField():判断是普通项还是文件项 true和false,如果true表示普通项,如果false表示文件上传项

getFieldName():获取普通项的name的名称

getString():获取普通项输入的值

getString(java.lang.String encoding):设置编码

getName():获取上传文件名称(加路径)

在某些浏览器里面,得到只是文件名称 没有路径 1.txt

getInputStream() :得到提交文件的输入流

delete():删除临时文件

(8)练习:js控制多文件的上传

有两个按钮:上传和增加

当点击增加,增加一个文件上传项和删除按钮

单点击删除,把删除按钮所在的那一行删除

点击上传,把页面上所有的文件上传到服务器

js代码

//增加方法

function add1() {

//得到div

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

//向div里面写html代码

divv.innerHTML += "<div><input type=‘file‘ name=‘file1‘ /> <input type=‘button‘ value=‘del‘ onclick=‘del1(this);‘/></div>";

}

//删除操作

function del1(who) {

//得到del按钮的所在的div

var div = who.parentNode;

//删除div

var divv = div.parentNode;

divv.removeChild(div);

}

(9)上传的问题解决

文件的重名的问题

如果多次上传相同的文件名称的文件,最后一次上传的文件会把之前文件覆盖

解决方式:

在文件名称后面加一个随机的字符串  abbcdfdfer_1.txt

得到随机的字符串: uuid得到唯一的字符串

//得到唯一的字符串 使用uuid

String uuid = UUID.randomUUID().toString();

//在文件之前添加uuid的值  uuid_filename

filename = uuid+"_"+filename;

上传的所有的文件都会放到一个文件夹里面,如果文件很多,读写很慢

在企业级开发中

根据时间进行分离: 根据年  月  天

根据用户进行分离:比如张三上传文件存到张三

根据文件数量进行分离:每3000个文件存到一个文件夹

使用目录分离的算法实现

首先得到文件的唯一的文件名

根据这个唯一的文件名.hashcode()操作,得到唯一的int值

使用得到的唯一的值,& 0xf 把结果作为第一级目录

使用int值,右移四位,再& 0xf,把结果作为第二级目录

int 32位,在计算机里面如何表示?

每四位表示一段 ,8段

2、文件的下载

(1)文件下载几种方式:两种

直接使用超链接实现 <a href="文件路径"></a>

这种方式不好,图片格式直接打开,而zip格式才会提示下载

写代码实现下载

步骤

//创建磁盘文件项工厂

DiskFileItemFactory factory = new DiskFileItemFactory();

//创建核心上传类

ServletFileUpload upload = new ServletFileUpload(factory);

upload.setHeaderEncoding("utf-8");

//解析request对象

List<FileItem> list = upload.parseRequest(request);

//创建Resource对象

Resource res = new Resource();

//遍历list集合

for (FileItem fileItem : list) {

//判断是否普通输入项

if(fileItem.isFormField()) {

String des = fileItem.getString("utf-8");

System.out.println(des);

res.setDes(des);

} else {//文件上传项

//得到上传文件名称  c:\a\a.txt

String filename = fileItem.getName();

int lens = filename.lastIndexOf("\\");

if(lens != -1) {

filename = filename.substring(lens+1);

}

//得到随机的字符串

String uuid = UUID.randomUUID().toString();

String uuidname = uuid+"_"+filename;

//得到上传文件夹的完全路径

String path = getServletContext().getRealPath("/uploadfile");

//得到分离之后的路径

String url = UploadUtils.getPath1(uuidname);

//判断文件夹是否存在,如果不存在,需要创建

File file = new File(path+url);

if(!file.exists()) {

file.mkdirs();

}

//得到上传文件

InputStream in = fileItem.getInputStream();

//使用输出流把文件写到文件夹里面

OutputStream out = new FileOutputStream(path+url+"/"+uuidname);

//流对接

int len = 0;

byte[] b = new byte[1024];

while((len=in.read(b))!=-1) {

out.write(b, 0, len);

}

//关闭流

in.close();

out.close();

//设置上传的信息

res.setUuidname(uuidname);

res.setRealname(filename);

res.setSavepath(path+url);

(2)代码实现文件的下载

//得到要下载文件的路径

String path = request.getParameter("filename");

path = new String(path.getBytes("iso8859-1"),"utf-8");

//  System.out.println("path::  "+path); c:\1\a.mp3

//得到文件名称

String filename = path.substring(path.lastIndexOf("\\")+1);

//处理不同的浏览器中文问题

//解决中文乱码问题

//得到当前请求的浏览器的类型

String agent = request.getHeader("User-Agent");

//如果是火狐浏览器

if(agent.contains("Firefox")) {

//base64编码

filename = "=?UTF-8?B?"+

new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?=";

} else {//ie浏览器

filename = URLEncoder.encode(filename, "utf-8");

}

//设置mime类型

String type = getServletContext().getMimeType(filename);

response.setContentType(type);

//设置头信息

response.setHeader("Content-Disposition", "attachment;filename="+filename);

//得到要下载文件的输入流

InputStream in = new FileInputStream(path);

//使用输出流把写到浏览器

OutputStream out = response.getOutputStream();

int len = 0;

byte[] b = new byte[1024];

while((len=in.read(b))!=-1) {

out.write(b, 0, len);

}

in.close();

(3)练习:给定任意的一个目录,把目录里面的所有的文件都显示出来(无论有多少层)

实现思路:

使用到树

树的遍历:深度优先遍历和广度优先遍历

可以使用队列实现树的遍历,队列特点是FIFO,先进先出

1、创建队列

- Queue<File> que = new LinkedList<File>();

- 入队:offer(E e)

- 出队:poll()

<%

//创建文件

File root = new File("f:\\1");

//创建队列

Queue<File> qu = new LinkedList<File>();

//把根节点入队

qu.offer(root);

//判断如果队列不为空

while(!qu.isEmpty()) {

//把根节点出队

File file = qu.poll();

//得到所有的文件和文件夹

File[] files = file.listFiles();

//遍历

for(File f : files) {

//判断是否是文件,如果是文件直接显示,不是文件继续入队

if(f.isFile()) {

%>

<a href="/day20/downlist?filename=<%=f.getCanonicalPath()%>"><%=f.getName() %></a> <br/>

<%

} else {//不是文件

//入队

qu.offer(f);

}

}

}

%>

2、把根节点入队,再把根节点出队

3、根节点出队之后,可以得到根节点的子节点

4、把子节点入队,在出队,获得子节点的子节点

依次类推....

实现文件的下载

//对文件名进行hashcode操作,返回int类型

int code1 = filename.hashCode();

//使用int值 & oxf

int d1 = code1 & 0xf;

//int值右移四位

int code2 = code1 >>> 4;

//把code2再&0xf

int d2 = code2 & 0xf;

return "/"+d1+"/"+d2;

}

时间: 2024-11-13 08:11:01

javaWeb系列之十七(上传下载)的相关文章

javaWeb中的文件上传下载

在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件.这个common-fileupload上传组件的jar包可以去apache官网上面下载,也可以在struts的lib文件夹下面找到,stru

JAVAWEB之文件的上传下载

文件上传下载 文件上传: 本篇文章使用的文件上传的例子使用的都是原生技术,servelt+jdbc+fileupload插件,这也是笔者的习惯,当接触到某些从未接触过的东西时,总是喜欢用最原始的东西将他们表达出来.下面是具体的步骤,大家可以跟着我一步一步的用apache的fileupload插件来完成文件的上传下载. 1.创建一个web工程,我们这里取名为fileupload 2.导入相关jar包,,数据源使用的是apache-c3p0数据源,以及上传下载插件包,goson库,以及mysql驱动

【JavaWeb】参考大神重新写的上传下载

自学java,选择从简单的javaweb入手了. 读了网上某位大神的细致文章,了解后自己写了这篇上传下载的,加上了自己一部分的理解注释. 算是入门篇吧.大致完成了任务,比较粗糙. fileHanderServlet.java (文件上传处理) 1 package up.file.Servletfile; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 i

C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)

原文:C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件) 微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C#微信公众号开发系列教程四(接收普通消息) C#微信公众号开发系列教程五(接收事件推送与消息排重) C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件) 第四,第五章已经讲了怎么处理用户发送的消息,本章就来讲讲怎么响应用户的

JavaWeb实现文件上传下载功能实例解析

转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件

JavaWeb学习总结——文件上传和下载

在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件.这个common-fileupload上传组件的jar包可以去apache官网上面下载,也可以在struts的lib文件夹下面找到,stru

JavaWeb实现文件上传下载功能实例解析 (好用)

转: 转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上

JavaWeb 文件上传下载

1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下载功能实现的. 文件上传下载实际上是两步操作,第一是文件上传,就是将本地文件上传到服务器端,实现文件多用户之间的共享,第二是文件下载,就是将服务器端的文件下载到本地磁盘. 1.2. 文件上传下载实现原理 首先,需要知道文件是如何实现上传及下载的.文件上传及下载实现原理如下: 文件上传实现流程如下:

Hadoop之HDFS原理及文件上传下载源码分析(下)

上篇Hadoop之HDFS原理及文件上传下载源码分析(上)楼主主要介绍了hdfs原理及FileSystem的初始化源码解析, Client如何与NameNode建立RPC通信.本篇将继续介绍hdfs文件上传.下载源解析. 文件上传 先上文件上传的方法调用过程时序图: 其主要执行过程: FileSystem初始化,Client拿到NameNodeRpcServer代理对象,建立与NameNode的RPC通信(楼主上篇已经介绍过了) 调用FileSystem的create()方法,由于实现类为Dis