java文件的上传与下载

本文详细介绍了文件上传与下载的核心技术实现,包括利用ServletFileUpload解析multipart/form-data请求、解决文件名乱码、限制上传文件大小、监听上传进度、生成随机目录避免文件冲突以及文件下载的响应头设置。
摘要由CSDN通过智能技术生成

1.首先了解遍历目录下文件的方法【file.list()和file.listFiles()】
在这里插入图片描述
2.建立工具类,获得随机目录
public static String generateRandomPath(String fileName) {
int hashcode = fileName.hashCode();
int d1 = hashcode & 0xf;
int d2 = (hashcode >> 4) & 0xf;
return “/” + d1 + “/” + d2;
}
3.文件的上传(核心代码如下)
// 先判断form是一个文件上传form
if (ServletFileUpload.isMultipartContent(request)) {
// 步骤一 构造工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置缓冲区大小和临时目录
factory.setSizeThreshold(1024 * 1024 * 8);// 8M 临时缓冲区(上传文件不大于8M
// 不会产生临时文件)
File repository = new File(getServletContext().getRealPath("/WEB-INF/tmp"));
factory.setRepository(repository);// 当上传文件超过8M 会在临时目录中产生临时文件

		// 步骤二 获得解析器
		ServletFileUpload upload = new ServletFileUpload(factory);
		final long start = System.currentTimeMillis();

		// 设置文件上传监听器
		ProgressListener listener = new ProgressListener() {
			@Override
			// 在文件上传过程中,文件上传程序,会自动调用update方法,而且不只一次调用,通过该方法,获得文件上传进度信息
			// pBytesRead 已经上传字节数量
			// pContentLength 上传文件总大小
			// pItems 表单项中第几项
			public void update(long pBytesRead, long pContentLength,
					int pItems) {
				System.out.println("上传文件总大小:" + pContentLength + ",已经上传大小:"
						+ pBytesRead + ", form第几项:" + pItems);
				// 通过运算获得其它必要信息:传输速度、剩余时间
				long currentTime = System.currentTimeMillis();
				// 已经使用时间
				long hasUseTime = currentTime - start;
				// 速率
				// 字节/毫秒 = x/1024*1000 KB/S
				long speed = pBytesRead / hasUseTime;
				// 剩余时间
				long restTime = (pContentLength - pBytesRead) / speed;// 毫秒
				System.out.println("传输速度:" + speed + "字节每毫秒,剩余时间"
						+ restTime + "毫秒");

				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		};

		upload.setProgressListener(listener);// 注册监听器

		// 解决上传文件名 乱码问题
		upload.setHeaderEncoding("utf-8");
		// 限制上传文件大小
		upload.setFileSizeMax(1024 * 1024 * 40);

		// 步骤三 对请求体内容进行解析
		try {
			List<FileItem> list = upload.parseRequest(request);
			// 步骤四 遍历FileItem 集合
			for (FileItem fileItem : list) {
				// 步骤五 判断每个FileItem 是不是文件上传项
				if (fileItem.isFormField()) {
					// 不是上传文件
					String name = fileItem.getFieldName(); // name属性
					String value = fileItem.getString("utf-8"); // value 属性
					System.out.println("普通form项:" + name + "----" + value);
				} else {
					// 是上传文件
					String filename = fileItem.getName(); // 文件名
					// 解决老版本浏览器IE6 文件路径存在问题
					if (filename.contains("\\")) {
						filename = filename.substring(filename
								.lastIndexOf("\\") + 1);
					}
					InputStream in = new BufferedInputStream(fileItem
							.getInputStream()); // 文件内容
					System.out.println("文件上传项:" + filename);
					// 保证上传文件名唯一
					filename = UUID.randomUUID().toString() + filename;
					// 生成随机目录
					String randomPath = UploadUtils.generateRandomPath(filename);// 生成目录不一定存在 ---创建
					File path = new File(getServletContext().getRealPath(
							"/WEB-INF/upload" + randomPath));
					path.mkdirs();

					// 将文件内容输出WEB-INF/upload 目录
					File targetFile = new File(path, filename);
					OutputStream out = new BufferedOutputStream(
							new FileOutputStream(targetFile));
					int temp;
					while ((temp = in.read()) != -1) {
						out.write(temp);
					}
					out.close();
					in.close();
					// 删除临时文件(必须将文件流关掉)
					fileItem.delete();
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
	}
}
4.文件的下载(核心代码如下)
	// 获得客户端提交file 参数
	String file = request.getParameter("file");
	// 下载文件,从服务器端读取文件,将文件内容写回客户端
	String serverFilePath = getServletContext().getRealPath("/download/" + file);

	// 设置响应头
	response.setContentType(getServletContext().getMimeType(file));// 根据文件扩展名获得MIME类型
	// 等级于 response.setHeader("Content-Type",xxx);
	response.setHeader("Content-Disposition", "attachment;filename=" + file);// 以附件下载

	InputStream in = new BufferedInputStream(new FileInputStream(
			serverFilePath));
	// 需要浏览器输出流
	OutputStream out = response.getOutputStream();
	int temp;
	while ((temp = in.read()) != -1) {
		out.write(temp);
	}
	out.close();
	in.close();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值