這是本文件的舊版!


InputStreamReader Encoding問題

今天開始寫main程式並透過batch去執行時,發現程式居然會印出失敗的錯誤訊息。奇怪的是,前幾天已經寫過單元測試並透過eclipse去執行以確認功能是正常的。在將log4j的debug打開後,就發現我所擷取的網頁內容,居然出現一堆亂碼,也造成parse程式出問題。
在經過trace一番,發現是使用InputStreamReader時,忽略了encoding。下面的程式碼,是透過HttpClient所取得的HttpResponse,並從它的inputStream取得內容並回傳。在Eclipse上,inputStreamReader.getEncoding()會log出utf8,但在windows batch中卻為ms950,這將會導致資料處理上發生亂碼問題。

	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();
	}

但是HttpClient的Post Header已經設定過UTF-8,且batch中也使用@chcp去切換code page。然而我疏忽的是InputStreamReader的Constructor:

	InputStreamReader inputStreamReader = new InputStreamReader(aResponse
				.getEntity().getContent(), "utf-8");
透過第二個參數,我們可以設定想要的encoding方式,讓讀出來的字串不會出現亂碼。這種編碼問題,也有可能會出現在Windows的wchar(JNA)、socket溝通、資料庫存取等,只要有中文字都有可能出問題(只有英文字不會=.=)! 到現在我覺得,還是UTF-8最好用。

友藏內心的獨白: 你說我stream沒close? 上一層透過httpclient api去close了拉!