zoukankan      html  css  js  c++  java
  • 用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
  • 相关阅读:
    LeetCode 345. Reverse Vowels of a String 题解
    LeetCode 344. Reverse String 题解
    LeetCode 27. Remove Element 题解
    LeetCode 61. Rotate List 题解
    LeetCode 19.Remove Nth Node From End of List 题解
    Android耗电量
    Android 使用adb查看和修改电池信息
    Android AOP AspectJ 插桩
    Flask相关用法
    Monkey日志信息的11种Event percentage
  • 原文地址:https://www.cnblogs.com/anic/p/2697475.html
Copyright © 2011-2022 走看看