Java实现文件上传和下载

上面的博文我写了Java对文件操作的功能https://blog.youkuaiyun.com/qq_24380635/article/details/83273359,这次记录一下文件上传和下载的功能。看看两者有什么不同,就可以知道文件操作和文件上传下载有什么不同了。我也是一点点懂,也希望给看过的人一些参考价值。

1、文件上传和下载的原理。我也参考了其他的博文,这里就不引用了,我完善一下。

文件上传原理

无论你使用的是springmvc框架还是struts2框架,在你前端的表单页面,提交方法都必须是post,enctype是multipart/form-data,这样做的目的只有一个,就是把表单以二进制方式提交给servlet,也方便servlet获取其中的内容。

看到下面enctype三种取值和解释你就会知道了:

1.application/x-www-form-urlencoded 这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成url编码方式.

2.multipart/form-data 这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里.

3.text/plain 这种方式主要适用于直接通过表单发送邮件的方式.

文件下载

1、设置HttpServletResponse.setContentType方法Content-Type头字段的值,下面使用application/force-download。这样做的目的就是告诉浏览器强制下载,不用跳转其他的。
2、设置HttpServletResponse.setHeader方法Content-Disposition头的值为"attachment;filename=文件名"。把文件附在头文件中。
3、在下载方法中调用HttpServletResponse.getOutputStream方法得到ServletOutputStream对象来向客户端写入附件文件内容.

    

对于文件上传下载这个,我考虑了几天,究竟用springmvc的transferTo好,还是使用IO流,并结合他的缓冲buffer好呢。我想了一下,struts怎么使用springmvc提供的文件上传呢!不能,那我就用IO流实现我的文件上传和下载,而且,IO流,也有一个FileChannel来的方法啊,它也有一个transferTo方法,这个方法的好不好呢?论坛人才多,自己看一下吧!反正我是觉得可以实现我的功能就好了。但是不能否认的是,springmvc提供的上传的确比IO流快。关于IO流,我在博客园有总结过。https://www.cnblogs.com/gaolt/p/9814723.html

 

/**
	 * 上传文件(单个)
	 * 
	 * @param file      文件对象
	 * @param uploadURl 上传目录绝对路径
	 * @return
	 */
	public static boolean upload(MultipartFile file, String savepath) {
		String newfileName = "";
		if (file.isEmpty()) {
			return false;
		}
		String filename = file.getOriginalFilename();
		File dest = new File(savepath, filename);
		if (dest.exists()) {
			newfileName = makeFileName(savepath, filename, 0);
		} else {
			newfileName = filename;
		}
		File newFile = new File(savepath, newfileName);
		if (!newFile.getParentFile().exists()) {
			newFile.getParentFile().mkdirs();
		}
		try {
			file.transferTo(newFile);
			return true;
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 上传文件(批量)
	 * 
	 * @param files
	 * @param uploadURl
	 * @return
	 */
	public static boolean multifileUpload(List<MultipartFile> files, String uploadURl) {
		for (int i = 0; i < files.size(); ++i) {
			MultipartFile file = files.get(i);
			if (!file.isEmpty()) {
				return upload(file, uploadURl);
			}
		}
		return false;
	}

	/**
	 * 下载文件
	 * 
	 * @param response
	 * @param downloadUrl 下载路径
	 * @param saveUrl     保存路径
	 * @param fileName    文件名称
	 * @return
	 */
	public static boolean download(HttpServletResponse response, String loadUrl) {
		File loadFile = new File(loadUrl);
		if (!loadFile.exists()) {
			System.out.println("下载的文件不存在");
			return false;
		}
		String fileName = loadFile.getName();
		response.setContentType("application/force-download");// 设置强制下载。application/force-download
		response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 将文件依附在头文件中
		byte[] buffer = new byte[1024];
		FileInputStream fis = null;
		BufferedInputStream bis = null;
		try {
			fis = new FileInputStream(loadFile);
			bis = new BufferedInputStream(fis);
			OutputStream os = response.getOutputStream();
			int len = 0;
			while ((len = fis.read(buffer, 0, len)) > 0) {
				os.write(buffer, 0, len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (bis != null) {
				try {
					bis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return true;
	}

/**
	 * 生成文件名:在相同文件夹内不允许相同的文件名存在
	 * 
	 * @param savepath 保存文件的路径
	 * @param fileName 文件名,带文件类型
	 * @param num      记录第几个文件同名了
	 * @return
	 */
	public static String makeFileName(String savepath, String fileName, int num) {
		int count = 2;
		String realName = "";
		String ExFileName = "";
		String newFileName = fileName;
		File saveFile = new File(savepath, fileName);
		if (fileName.contains(".")) {
			ExFileName = fileName.substring(fileName.lastIndexOf(".") + 1);
		}
		StringBuffer sbf = new StringBuffer();
		if (num >= 2) {
			count = num + 1;
		}
		if (saveFile.exists()) {
			if (fileName.contains("(")) {
				realName = fileName.substring(0, fileName.indexOf("(")).trim();
			} else {
				if (ExFileName == null || ExFileName.equals("")) {
					realName = fileName;
				} else {
					realName = fileName.substring(0, fileName.lastIndexOf("."));
				}
			}
			sbf.append(realName);
			sbf.append(" (" + count + ")");
			if (ExFileName != null && !ExFileName.equals("")) {
				sbf.append(".");
			}
			sbf.append(ExFileName);
			newFileName = sbf.toString();
			// 使用递归
			num = count;

			newFileName = makeFileName(savepath, newFileName, num);
		}
		return newFileName;
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值