差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

java:basic:inputstreamreaderencoding [2017/08/19 23:33]
java:basic:inputstreamreaderencoding [2023/06/25 09:48] (目前版本)
行 1: 行 1:
 +{{tag>​java}}
 +====== InputStreamReader Encoding問題 ======
 +今天開始寫main程式並透過batch去執行時,發現程式居然會印出失敗的錯誤訊息。奇怪的是,前幾天已經寫過單元測試並透過eclipse去執行以確認功能是正常的。在將log4j的debug打開後,就發現我所擷取的網頁內容,居然出現一堆亂碼,也造成parse程式出問題。\\
 +在經過trace一番,發現是使用InputStreamReader時,忽略了encoding。下面的程式碼,是透過HttpClient所取得的HttpResponse,並從它的inputStream取得內容並回傳。在Eclipse上,inputStreamReader.getEncoding()會log出utf8,但在windows batch中卻為ms950,這將會導致資料處理上發生亂碼問題。
 +<code java>
 + public static String getReponseContent(HttpResponse aResponse)
 + throws IOException {
 + InputStreamReader inputStreamReader = new InputStreamReader(aResponse
 + .getEntity().getContent());​
  
 + BufferedReader br = new BufferedReader(inputStreamReader);​
 +
 + StringBuffer content = new StringBuffer();​
 + int i;
 + while ((i = br.read()) != -1) {
 + content.append((char) i);
 + }
 +
 + logger.debug("​Encoding:​ {}", inputStreamReader.getEncoding());​
 + logger.debug("​HttpEntityStatus:​ {}", aResponse.getStatusLine());​
 + logger.debug("​HttpEntiyInfo:​\n{}",​ content.toString());​
 + return content.toString();​
 + }
 +</​code>​
 +
 +但是HttpClient的Post Header已經設定過UTF-8,且batch中也使用@chcp去切換code page。然而我疏忽的是InputStreamReader的Constructor:
 +<code java> ​
 + InputStreamReader inputStreamReader = new InputStreamReader(aResponse
 + .getEntity().getContent(),​ "​utf-8"​);​
 +</​code>​
 +透過第二個參數,我們可以設定想要的encoding方式,讓讀出來的字串不會出現亂碼。這種編碼問題,也有可能會出現在Windows的wchar(JNA)、socket溝通、資料庫存取等,只要有中文字都有可能出問題(只有英文字不會=.=)! 到現在我覺得,還是UTF-8最好用。
 +
 +友藏內心的獨白:​ 你說我stream沒close?​ 上一層透過httpclient api去close了拉!
 +
 +=====    =====
 +----
 +\\
 +~~DISQUS~~