2015-09-03 48 views
1

我有一個簡單的servlet類將CSV文件返回給客戶端(瀏覽器)。當我試圖寫入字符串流。最初我遵循例子A),但我注意到預期數據的子集被追加。在java中將輸出流寫入字符串

比方說,我預計精確的100個記錄將被捕獲在一個csv文件中。每個記錄代表「名/姓/年齡」。在例子A)中,我得到了120個。前100個記錄是正確的,但是在這個例子中是20個(重複)的100個子集被追加。

例A)

public void returnCSV(HttpServletResponse resp, String data) { 
    ServletOutputStream out = resp.getOutputStream(); 
    InputStream in = new ByteArrayInputStream(data.getBytes("UTF-8")); 
    byte[] bytes = new byte[4096]; 
    while (in.read(bytes,0,4096) != -1) { 
     out.write(bytes,0,4096); 
    } 
    in.close(); 
    out.flush(); 
    out.close(); 
} 

讀取關於多個線程轉換字符串流之後。我決定按照例B)生成正確的輸出100條記錄。但我不明白爲什麼第一個例子A)會添加重複的數據。

例如B)

public void returnCSV(HttpServletResponse resp, String data) { 
    ServletOutputStream out = resp.getOutputStream(); 
    out.write(data.getBytes("UTF-8"));   
    out.flush(); 
    out.close(); 
} 

回答

1

看這個循環:

while (in.read(bytes,0,4096) != -1) { 
    out.write(bytes,0,4096); 
} 

但是大量的數據被讀取read,你總是寫出4096個字節。您只想複製您讀取的相同數量的數據,例如

int bytesRead; 
while ((bytesRead = in.read(bytes)) != -1) { 
    out.write(bytes, 0, bytesRead); 
} 

有很多具有代碼從輸入流複製到輸出流的第三方庫的,你要知道 - 你應該使用try-與資源語句仍要關閉流。

此外,您應該調用ServletResponse.getWriter,而不是調用getOutputStream,可能在調用ServletResponse.setCharacterEncoding後確保其使用UTF-8。然後你可以撥打電話:

writer.write(data); 

作家被設計來寫文本數據;輸出流被設計爲寫入二進制數據。您可以使用OutputStreamWriter在流的頂部創建一個編寫器,但由於servlet API將爲您執行該操作,因此您可能會放過它...

+0

謝謝您的解釋和建議。 – DaeYoung

+0

resp.setCharacterEncoding(「UTF-8」); 。resp.getWriter()寫(數據);非常棒!謝謝! – DaeYoung