用java在Windows控制台輸出utf8字符


最近開發java控制台項目,由於用了第三方庫,必須使用utf8字符。當然在開發環境eclipse下,顯示是正常的:

image

 

但是windows的控制台,卻是輸出亂碼。

image

 

 

雖然不改,程序邏輯是正確,作為偏執狂還是翻閱了各種資料:

http://www.cnblogs.com/QQParadise/articles/1685177.htm

http://dustin.iteye.com/blog/77551

網上各種文章,不是用chcp改變控制台編碼,就是建議修改程序編碼為GBK。

 

參考了stackoverflow的一篇文章,找到一種使用Windows內核API的方案

http://stackoverflow.com/questions/54952/java-utf-8-and-windows-console

 

核心是封裝一個Console類

package demo;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;

/**
 * For unicode output on windows platform
 * 
 * @author Sandy_Yin
 * 
 */
public class Console {
	private static Kernel32 INSTANCE = null;

	public interface Kernel32 extends StdCallLibrary {
		public Pointer GetStdHandle(int nStdHandle);

		public boolean WriteConsoleW(Pointer hConsoleOutput, char[] lpBuffer,
				int nNumberOfCharsToWrite,
				IntByReference lpNumberOfCharsWritten, Pointer lpReserved);
	}

	static {
		String os = System.getProperty("os.name").toLowerCase();
		if (os.startsWith("win")) {
			INSTANCE = (Kernel32) Native
					.loadLibrary("kernel32", Kernel32.class);
		}
	}

	public static void print(String message) {
		if (!prePrint(message))
			System.out.print(message);

	}

	protected static boolean prePrint(String message) {
		boolean successful = false;
		if (INSTANCE != null) {
			Pointer handle = INSTANCE.GetStdHandle(-11);
			char[] buffer = message.toCharArray();
			IntByReference lpNumberOfCharsWritten = new IntByReference();
			successful = INSTANCE.WriteConsoleW(handle, buffer, buffer.length,
					lpNumberOfCharsWritten, null);
		}
		return successful;
	}

	public static void println(String message) {
		// from
		// http://stackoverflow.com/questions/54952/java-utf-8-and-windows-console
		if (prePrint(message)) {
			System.out.println();
		} else {
			System.out.println(message);
		}
	}
}
對輸出進行測試,使用命令:java -jar sample.jar,發現輸出還是一樣。
image
添加命令行參數,使用java -Dfile.encoding=utf8 -jar sample.jar,就達到效果了。
image

PS:此方法還存在一些缺陷,但並不是Console類造成的。上圖中“測試”前有一個空白的地方,這是應為使用utf8方式讀入非UTF8文件產生的。在文件開始會出現空格。

代碼下載

/Files/anic/utf8sample_source.zip
/Files/anic/utf8sample_runtime.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM