1. 程式人生 > >Java實現檔案上傳和下載

Java實現檔案上傳和下載

上面的博文我寫了Java對檔案操作的功能https://blog.csdn.net/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;
	}