IO流下載檔案
IO流的下載,今天專案寫的,遇到的問題都會寫在下面,如有哪裡寫的不好,輕噴。:
IO流簡介:
流的定義:流是指一連串流動的字元,是以先進先出方式傳送資訊的通道。
按流向分:輸出流:OutputStream和Writer為基類
輸入流:InputStream和Reader為基類
按處理資料單元劃分:位元組流:位元組輸入流:InputStream基類
位元組輸出流:OutputStream基類
字元流:字元輸入流:Reader
位元組輸出流:Writer基類
(位元組流是 8 位通用位元組流,字元流是16位Unicode字元流**)
public void download(HttpServletRequest request, HttpServletResponse response) {
InputStream fis=null;
OutputStream toClient=null;
try {
//獲取下載的路徑
File file=new File("C:\\Users\\kinggao1\\Desktop\\工作周總結.docx");
//獲取檔名
String filename=file.getName();
//取得檔案的字尾名
String ext=filename.substring(filename.lastIndexOf(".")+1).toUpperCase();
//以流的形式下載檔案
fis=new BufferedInputStream(new FileInputStream(file));
System.out .println("檔案大小:"+fis.available());
//建立一個和檔案一樣大小的快取區
byte[] buffer=new byte[fis.available()];
//讀取流
fis.read(buffer);
//清空首部空白行
response.reset();
//設定檔案下載後的指定檔名
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("gb2312"),"ISO8859-1"));
response.addHeader("Content-Length", "" + file.length());
//response.getOutputStream() 獲得位元組流,通過該位元組流的write(byte[] bytes)可以向response緩衝區中寫入位元組,再由Tomcat伺服器將位元組內容組成Http響應返回給瀏覽器。
toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
//將buffer 個位元組從指定的 byte 陣列寫入此輸出流。
toClient.write(buffer);
//重新整理此緩衝的輸出流。這迫使所有緩衝的輸出位元組被寫出到底層輸出流中。 把快取區的資料全部寫出
toClient.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//關閉流
fis.close();
//關閉緩衝輸出流
toClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- response.addHeader
檔案下載,指定預設名
Response.AddHeader("content-type","application/x-msdownload"); // 限制類型
Response.AddHeader("Content-Disposition","attachment;filename=檔名.rar");// 下載後的檔名,這裡如果檔名是中文,在下載時會出現亂碼
Tips
response.setHeader()下載中文檔名亂碼問題
response.setHeader(“ContentDisposition”,”attachment;filename=”+java.net.URLEncoder.encode(fileName, “UTF-8”));
下載的程式裡有了上面一句,一般在IE6的下載提示框上將正確顯示檔案的名字,無論是簡體中文,還是日文。不過當時確實沒有仔細測試檔名為很長的中文檔名的情況。現如今經過仔細測試,發現文字只要超過17個字,就不能下載了。分析如下:
一. 通過原來的方式,也就是先用URLEncoder編碼,當中文文字超過17個時,IE6 無法下載檔案。這是IE的bug,參見微軟的知識庫文章 KB816868 。原因可能是IE在處理 Response Header 的時候,對header的長度限制在150位元組左右。而一個漢字編碼成UTF-8是9個位元組,那麼17個字便是153個位元組,所以會報錯。而且不跟字尾也不對.
二. 解決方案:將檔名編碼成ISO8859-1是有效的解決方案,程式碼如下:
response.setHeader(“ContentDisposition”,”attachment;filename=”+newString(fileName.getBytes(“gb2312”), “ISO8859-1” ) );
在確保附件檔名都是簡體中文字的情況下,那麼這個辦法確實是最有效的,不用讓客戶逐個的升級IE。如果臺灣同胞用,把gb2312改成big5就行。但現在的系統通常都加入了 國際化的支援,普遍使用UTF-8。如果檔名中又有簡體中文字,又有繁體中文,還有日文。那麼亂碼便產生了。另外,在上Firefox (v1.0-en)下載也是亂碼。
- BufferedInputStream
帶緩衝區的輸入流,預設緩衝區大小是8M,能夠減少訪問磁碟的次數,提高檔案讀取效能;
是 FileInputStream 的子類。 實現了裝飾設計模式!
BufferedInputStream沒有無參構造方法,它必須傳入一個InputStream(一般是FileInputStream),來一起使用,以提高讀寫效率。
構造方法:
1、BufferInputStream(InputStream in)// 建立一個 BufferedInputStream 並儲存其引數,即輸入流 in,以便將來使用。
建立一個內部緩衝區陣列並將其儲存在 buf 中,該buf的大小預設為8192。
2、BufferedInputStream(InputStream in, int size) //建立具有指定緩衝區大小的 BufferedInputStream 並儲存其引數,即輸入流 in,以便將來使用。
建立一個長度為 size 的內部緩衝區陣列並將其儲存在 buf 中。
- BufferedOutputStream
帶緩衝區的輸出流,能夠提高檔案的寫入效率。實現了裝飾設計模式!
BufferedOutputStream沒有無參構造方法,它必須傳入一個OutputStream(一般是FileOutputStream),來一起使用,以提高讀寫效率。
構造方法:
1、BufferOutputStream(**OutputStream outs**)// 建立一個 BufferedInputStream 並儲存其引數,即輸出流outs,將資料寫入指定的基本輸入流中。
2、BufferedOutputStream(OutputStream outs, int size) //建立具有指定緩衝區大小的 BufferedOutputStream ,即輸出流outs,將資料寫入指定的基本輸入流中 。
第一次寫部落格,寫的不好請輕噴!很多都是百度的,所有還是也會有不理解的,大佬們如有好的意見,可以提出來。畢竟是個菜鳥!