<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    小明思考

    Just a software engineer
    posts - 124, comments - 36, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    Java 控制臺中文問題(windows平臺)

    Posted on 2012-01-19 16:18 小明 閱讀(3717) 評論(1)  編輯  收藏 所屬分類: 開發(fā)日志
    測試代碼

     1 import java.io.Console;
     2 import java.lang.reflect.Constructor;
     3 import java.lang.reflect.Field;
     4 import java.nio.charset.Charset;
     5 
     6 public class JsTest {
     7     
     8     @SuppressWarnings("rawtypes")
     9     private static void outputCharset(){
    10         Constructor[] ctors = Console.class.getDeclaredConstructors();
    11         Constructor ctor = null;
    12         for (int i = 0; i < ctors.length; i++) {
    13             ctor = ctors[i];
    14             if (ctor.getGenericParameterTypes().length == 0)
    15                 break;
    16         }
    17         try {
    18             ctor.setAccessible(true);
    19             Console c = (Console) ctor.newInstance();
    20             Field f = c.getClass().getDeclaredField("cs");
    21             f.setAccessible(true);
    22             System.out.println(String.format("Console charset:%s",
    23                     f.get(c)));
    24             System.out.println(String.format("Charset.defaultCharset():%s",
    25                     Charset.defaultCharset()));
    26         } catch (Exception x) {
    27             x.printStackTrace();
    28         }
    29     }
    30     
    31     public static void main(String[] args) {
    32         outputCharset();
    33         System.out.println("1234中文5678");
    34     }
    35 }

    編碼
    有兩個編碼需要提及的是:
    1. Console charset(控制臺編碼)
    控制臺編碼是windows的命令行窗口的編碼,可以使用chcp來查看,也可以是窗口屬性中看到。
    我的是英文的Windows XP加上了中文支持。(在控制面板的Region中設置)

    2. System default Charset(系統(tǒng)默認編碼)
    這個是系統(tǒng)默認編碼,windows英文操作系統(tǒng)是cp1252(iso-8859-1)

    試驗
    編譯:
    javac -encoding utf8 JsTest.java
    因為我的源代碼用utf8存貯,所以編譯的時候加上了utf8選項。

    測試1:
    java  zzz.JsTest

    Java把字符串直接通過default Charset[windows-1252(iso-8859-1)]轉化后輸出到控制臺,但是這個控制臺只能識別code936(gb2312)的編碼,所以不能識別,
    輸出??

    測試2:
    指定file.encoding來改變default charset為gb2312,這下okay了
    java -Dfile.encoding=gb2312 zzz.JsTest

    測試3:
    換成utf8看看,變成亂碼。
    Java -Dfile.encoding=utf8 zzz.JsTest

    測試4:
    通過chcp來改變控制臺編碼,行不通。

    結論
    1. 只有console charset 和 system default charset保持一致才不會亂碼
    2. chcp 65001(utf8)不能正常工作
    3. 可以通過-Dfile.encoding改變default charset

    解決方案
    因為我們無法控制console的編碼,如何能確保程序總是能正確輸出,即使程序被放在日文OS上執(zhí)行?

    native unicode output
    這種方案使用Windows Native API WriteConsoleW來輸出,這樣總是以unicode輸出。(使用了JNA)

    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 println(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);
                
    if(successful){
                    System.out.println();
                }
            }
            
    if (!successful) {
                System.out.println(message);
            }
        }
    }



    評論

    # re: Java 控制臺中文問題(windows平臺)  回復  更多評論   

    2012-01-23 23:13 by tb
    很好啊
    主站蜘蛛池模板: 亚洲欧洲日韩国产一区二区三区| 亚洲精品第五页中文字幕| 亚洲乱码中文字幕在线| 久久久久久久久免费看无码| 中文字幕在线观看亚洲视频| 免费中文熟妇在线影片 | 国产电影午夜成年免费视频| 亚洲邪恶天堂影院在线观看| 日本xxxx色视频在线观看免费| 亚洲成a人片在线观看日本| 无码日韩精品一区二区免费暖暖| 亚洲国产女人aaa毛片在线| 91香焦国产线观看看免费| 7777久久亚洲中文字幕蜜桃 | 亚洲制服丝袜中文字幕| 99视频在线精品免费观看6| 亚洲国产成人AV在线播放| 国产一级淫片视频免费看| 成年大片免费高清在线看黄| 国产亚洲AV手机在线观看| 久久久久久一品道精品免费看| 亚洲v高清理论电影| 国产一卡二卡3卡四卡免费| 中文字幕亚洲情99在线| 无码欧精品亚洲日韩一区夜夜嗨| 波霸在线精品视频免费观看| 久久久久亚洲精品无码系列| 日韩版码免费福利视频| 男女猛烈xx00免费视频试看| 国产亚洲视频在线播放| 精品久久8x国产免费观看| 亚洲人成电影网站色| 国产精品亚洲mnbav网站| 日韩免费人妻AV无码专区蜜桃| 国产成人精品亚洲2020| 亚洲精品成人在线| 59pao成国产成视频永久免费 | 一二三四视频在线观看中文版免费 | g0g0人体全免费高清大胆视频| 亚洲色欲色欲综合网站| 国产精品国产午夜免费福利看|