一、web开发文件上传功能:
方式概况:
1、将form表单中的enctype属性设为:multipart/form-data ,method设为post提交
2、将input的type属性设为file属性,必须给input设一个name属性否则提交不上去;
3、servlet中提供Request方法中的getInputStream方法---------------》通过这个方法可以读取到客户端的数据,比较麻烦,所以使用Apacha提供的方法。
核心API--DiskFileItemFactory
public DiskFileItemFactory(){}
public void setSizeThreshold(int size){设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时, fileupload组件将使用临时文件缓存上传文件}
public void setRepository(){指定文件的临时目录,默认值为:System.getProperty}
核心API--ServletFileUpload
boolean isMultipartContent(HttpServletRequest request){判断request传递的表单是否是文件上传的表单----》enctype属性设为:multipart/form-data }
List parseRequest(HttpServletRequest request){解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合}
setFileSizeMax(long fileSizeMax) {设置上传文件的最大值}
setSizeMax(long sizeMax) {设置上传文件总量的最大值}
setHeaderEncoding(java.lang.String encoding){设置编码格式}
setProgressListener(ProgressListener pListener) {显示上传速度}
ProgressListener progressListener = new ProgressListener() {
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("到现在为止, " + pBytesRead + " 字节已上传,总大小为 "
+ pContentLength);
}
};
upload.setProgressListener(progressListener);
//以KB为单位显示上传进度
long temp = -1; //temp注意设置为类变量
long ctemp = pBytesRead /1024;
if (mBytes == ctemp)
return;
temp = mBytes;
4、实现步骤:
1、创建DiskFileItemFactory对象,设置缓冲区大小和临时文件目录
2、使用DiskFileItemFactory 对象创建ServletFileUpload对象,并设置上传文件的大小限制。
3、调用ServletFileUpload.parseRequest方法解析request对象,得到一个保存了所有上传内容的List对象。
4、对list进行迭代,每迭代一个FileItem对象,调用其isFormField方法判断是否是上传文件
为普通表单字段,则调用getFieldName、getString方法得到字段名和字段值
为上传文件,则调用getInputStream方法得到数据输入流,从而读取上传数据。
编码实现文件上传
5、具体案例:
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
//创建上传的核心类
ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
//设置编码
fileUpload.setHeaderEncoding("utf-8");
//设置表单文件大小
fileUpload.setSizeMax(1024 * 1024 * 20);
//遍历取值
if (fileUpload.isMultipartContent(request)) {
try {
List<FileItem> list = fileUpload.parseRequest(request);
for (FileItem fileItem : list) {
if (fileItem.isFormField()) {
String strname = fileItem.getFieldName();
String strvalues = new String(fileItem.getString().getBytes("ISO8859-1"), "utf-8");
map.put(strname, strvalues);
} else {
//保存路径
rolepath = request.getServletContext().getRealPath("/upload");
File file = new File(rolepath);
if (!file.exists()) {
file.mkdirs();
}
//上传的文件名
nameend = fileItem.getName();
if (nameend == "" || nameend == null) {
img = "E:\\ShiXun\\dayproject\\047-fenyezuoye\\tp\\2018_10_06_19_13_IMG_6827.JPG";
} else {
upname = UpdateUtlis.cerename(nameend);
img = rolepath + "\\" + upname;
}
//写入文件
fileItem.write(new File(file, upname));
fileItem.delete();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
6、文件上传时的中文乱码问题:
文件名中文乱码问题,可调用ServletUpLoader的setHeaderEncoding方法,或者设置request的setCharacterEncoding属性 ;
7、文件上传的临时目录删除问题:
由于文件大小超出DiskFileItemFactory.setSizeThreshold方法设置的内存缓冲区的大小时,Commons-fileupload组件将使用临时文件保存上传数据,
因此在程序结束时,务必调用FileItem.delete方法删除临时文件。
Delete方法的调用必须位于流关闭之后,否则会出现文件占用,而导致删除失败的情况。
8、文件上传储存在服务器的目录问题:
/**
* 一般在公司中 文件上传的文件放哪里呢?
* 1.存在自己公司的服务上
* 2.存到第三方服务上 比如七牛云
* 3.存到当前项目的目录中
*/
为保证服务器安全,上传文件应保存在应用程序的WEB-INF目录下,或者不受WEB服务器管理的目录。
为防止多用户上传相同文件名的文件,而导致文件覆盖的情况发生,文件上传程序应保证上传文件具有唯一文件名。
为防止单个目录下文件过多,影响文件读写速度,处理上传文件的程序应根据可能的文件上传总量,选择合适的目录结构生成算法,将上传文件分散存储。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一、web开发文件下载功能:
Web应用中实现文件下载的两种方式:
1、超链接直接指向下载资源;
2、程序实现下载需设置两个响应头:
设置Content-Type 的值为:application/x-msdownload。Web 服务器需要告诉浏览器其所输出的内容的类型不是普通的文本文件或 HTML 文件,而是一个要保存到本地的下载文件。
Web 服务器希望浏览器不直接处理相应的实体内容,而是由用户选择将相应的实体内容保存到一个文件中,这需要设置 Content-Disposition 报头。
该报头指定了接收程序处理数据内容的方式,在 HTTP 应用中只有 attachment 是标准方式,attachment 表示要求用户干预。在 attachment 后面还可以指定 filename 参数,该参数是服务器建议浏览器将实体内容保存到文件中的文件名称。
在设置 Content-Dispostion 之前一定要指定 Content-Type.
response.setHeader("content-disposition", "attachment;fileName="+name);
因为要下载的文件可以是各种类型的文件,所以要将文件传送给客户端,其相应内容应该被当做二进制来处理,所以应该调用
方法返回 ServeltOutputStream 对象来向客户端写入文件内容。
实现步骤:
int uid = Integer.parseInt(request.getParameter("uid"));
String name = "学生管理系统";
User user=userService.findUser(uid);
File file=new File(user.getImg());
InputStream inputStream=new FileInputStream(file);
response.setHeader("content-disposition", "attachment;fileName="+name);
OutputStream outputStream=response.getOutputStream();
byte[] bytes=new byte[8*1024];
int len=-1;
while ((len=inputStream.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
inputStream.close();
outputStream.close();