1. 程式人生 > >javaweb通過介面來實現多個檔案壓縮和下載(包括單檔案下載,多檔案批量下載)

javaweb通過介面來實現多個檔案壓縮和下載(包括單檔案下載,多檔案批量下載)


  程式設計師在做web等專案的時候,往往都需要新增檔案上傳、下載、刪除的功能,有時是單檔案,有時多檔案批量 操作,而這些功能的程式碼程式設計師可以自己收藏起來當成工具使用,這樣,程式設計師在進行程式設計的時候就會事半功倍 了,那麼接下來的部落格將會介紹各個框架的檔案上傳和下載功能的使用方法。 

  這篇博文主要是講如何將多個檔案壓縮並下載下來:

 主要有以下幾個步驟:

1。 首先先遍歷出某個資料夾所含有的所有檔案

import java.io.File;
import java.util.Vector;
public class A {
 public static void recursion(String root, Vector<String> vecFile) {
/*根據路徑生成一個檔案*/
  File file = new File(root);
  File[] subFile = file.listFiles();
/*遍歷檔案裡面的所有檔案*/
  for (int i = 0; i < subFile.length; i++) {
/*如果是資料夾,則遞迴下去尋找資料夾裡面的檔案*/
if (subFile[i].isDirectory()) { recursion(subFile[i].getAbsolutePath(), vecFile); } else {
/*如果不是資料夾的話就直接新增到vector容器裡面去
(vector類稱作向量類,它實現了動態陣列,用於元素數量變化的物件陣列。像陣列一樣,vector類也用從0開始的下標表示元素的位置;但和陣列不同的是,當vector物件建立後,陣列的元素個數會隨著vector物件元素個數的增大和縮小而自動變化。)*/
2.將遍歷出來的檔案進行壓縮和下載:

String filename = subFile[i].getName();
    vecFile.add(filename);
   }
  }
 }
 public static void main(String[] args) {
  Vector<String> vecFile = new Vector<String>();
  recursion("D:/logs/2", vecFile);
  
  for (String fileName : vecFile) {
   System.out.println(fileName);
  }
 }
} 

2。 將遍歷出來的檔案進行壓縮和下載:(一個一個壓縮)

2.1 設定下載檔案的名稱

String fileName = "temp1.zip";
		response.setContentType("text/html; charset=UTF-8"); // 設定編碼字元
		response.setContentType("application/x-msdownload"); // 設定內容型別為下載型別
		response.setHeader("Content-disposition", "attachment;filename=" + fileName);// 設定下載的檔名稱
		OutputStream out = response.getOutputStream(); // 建立頁面返回方式為輸出流,會自動彈出下載框
		System.out.println("配置成功");

2.2 建立壓縮檔案需要的空的zip包

String zipBasePath = request.getSession().getServletContext().getRealPath("/logs/2/");

		/* 輸出basePath的路徑,方便除錯 */
		System.out.println(zipBasePath);
		/* 建立壓縮檔案需要的空的zip包 ,這裡是自動生成的,不用我們自己去生成 */
		String zipFilePath = zipBasePath + "temp.zip";
		System.out.println("create the empty zip file successfully??????");

2.3 根據臨時的zip壓縮包路徑,建立zip檔案

File zip = new File(zipFilePath);
		if (!zip.exists()) {
			zip.createNewFile();
		}
System.out.println("create the  zip file successfully");

2.4 建立zip檔案輸出流

FileOutputStream fos = new FileOutputStream(zip);
		ZipOutputStream zos = new ZipOutputStream(fos);
		System.out.println("create the empty zip stream successfully");

2.5 迴圈讀取檔案路徑集合,獲取每一個檔案的路徑(將檔案一個一個進行壓縮)

for (String fp : vecFile) {
			File f = new File(fp); // 根據檔案路徑建立檔案
			zipFile(f, zos); // 將每一個檔案寫入zip檔案包內,即進行打包
		}
		System.out.println("get the path successfully");
               // fos.close();//如果這樣關兩次的話會報錯,java.io.IOException: Stream closed
                zos.close();
		System.out.println("ok??");

2.6 將打包後的檔案寫到客戶端,有兩種方法可以實現(下面會進行介紹),這裡使用緩衝流輸出

InputStream fis = new BufferedInputStream(new FileInputStream(zipFilePath));
		byte[] buff = new byte[4096];
		int size = 0;
		while ((size = fis.read(buff)) != -1) {
			out.write(buff, 0, size);
		}
		System.out.println("package is packed successfully");

2.7 釋放和關閉輸入輸出流

                out.flush();//清楚快取
		out.close();
		fis.close();

2.8 檔案壓縮的方法

	public void zipFile(File inputFile, ZipOutputStream zipoutputStream) {
		try {
			if (inputFile.exists()) { // 判斷檔案是否存在
				if (inputFile.isFile()) { // 判斷是否屬於檔案,還是資料夾

					// 建立輸入流讀取檔案
					FileInputStream fis = new FileInputStream(inputFile);
					BufferedInputStream bis = new BufferedInputStream(fis);

					// 將檔案寫入zip內,即將檔案進行打包
					ZipEntry ze = new ZipEntry(inputFile.getName()); // 獲取檔名
					zipoutputStream.putNextEntry(ze);

					// 寫入檔案的方法,同上
					byte[] b = new byte[1024];
					long l = 0;
					while (l < inputFile.length()) {
						int j = bis.read(b, 0, 1024);
						l += j;
						zipoutputStream.write(b, 0, j);
					}
					// 關閉輸入輸出流
					bis.close();
					fis.close();
				} else { // 如果是資料夾,則使用窮舉的方法獲取檔案,寫入zip
					try {
						File[] files = inputFile.listFiles();
						for (int i = 0; i < files.length; i++) {
							zipFile(files[i], zipoutputStream);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

這個是我在團隊中的一個專案開發過程。在這個過程中,我主要遇到了幾個常見的問題,不過最後都一一被我解決掉了。

1. 因為我要下載壓縮的檔案是一個日誌不斷動態生成的檔案,所以需要先對其複製到另外一個資料夾再進行壓縮以及下載;

2. 對IO流的一些 知識不是很熟悉(學習並參考:https://blog.csdn.net/weixin_37766296/article/details/80070847)

檔案從一個資料夾複製到另一個資料夾:

   // 讀寫檔案
    public static void copy1() throws Exception{  
        FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\1\\log.txt");(原檔案路徑)  
        FileOutputStream fos = new FileOutputStream("D:\\java1\\eclipse\\javadownload\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp1\\wtpwebapps\\SCNU_OAuth2\\logs\\1\\log.txt");  
        int len = 0;  
        byte[] buf = new byte[1024];  
        while ((len = fis.read(buf)) != -1) {  
            fos.write(buf, 0, len);  
        }  
        fos.close();  
        fis.close();  
    } 
/*複製過去之後格式發生了變化,故放棄這個方法*/
	public void copy2() {
		FileWriter fw = null;
		BufferedReader br = null;
		try {
			fw = new FileWriter(
					"D:\\java1\\eclipse\\javadownload\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp1\\wtpwebapps\\SCNU_OAuth2\\logs\\1\\log.txt",
					true);
			br = new BufferedReader(new InputStreamReader(
					new FileInputStream("C:\\Users\\Administrator\\Desktop\\1\\log.txt"), "UTF-8"));(原檔案路徑)
			String line = null;
			while ((line = br.readLine()) != null) {
				// System.out.println("檔案內容: " + line);
				fw.write(line);
				fw.flush();
			}
			br.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fw != null) {
				try {
					fw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}


對於單個檔案下載:

可以參考:https://blog.csdn.net/alan_liuyue/article/details/72772502

參考博文:https://blog.csdn.net/alan_liuyue/article/details/72772502(裡面關於流的關閉有點瑕疵)

歡迎大家前來討論~