<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
    很好啊
    主站蜘蛛池模板: 亚洲午夜久久久久久久久电影网| 亚洲女子高潮不断爆白浆| 青青久久精品国产免费看| 在线免费视频一区二区| 亚洲砖码砖专无区2023| 成全影视免费观看大全二| 亚洲人成免费电影| 成人免费视频88| 亚洲国产成人综合精品| 国产一区二区三区免费视频| 老司机午夜在线视频免费| 无码欧精品亚洲日韩一区夜夜嗨| 精品无码一区二区三区亚洲桃色| 无码人妻一区二区三区免费n鬼沢| 亚洲精品无码专区久久久 | 亚洲第一区精品日韩在线播放| 亚洲日本VA中文字幕久久道具| 成人免费在线观看网站| 豆国产96在线|亚洲| 亚洲精品无码av天堂| 精品国产一区二区三区免费| 亚洲高清不卡视频| 午夜成年女人毛片免费观看| 粉色视频在线观看www免费| 亚洲无人区一区二区三区| 18pao国产成视频永久免费| 波多野结衣亚洲一级| 亚洲第一区精品观看| 最近中文字幕完整免费视频ww| 亚洲国产人成在线观看| 国产精品成人四虎免费视频| 一级有奶水毛片免费看| 亚洲乱码一二三四区麻豆| 四虎影院免费在线播放| 中文字幕免费在线播放| 亚洲国产成人精品久久| 亚洲精品久久久www | 成人无码a级毛片免费| 亚洲av永久无码精品三区在线4| 日本成人在线免费观看| 日本免费电影一区二区|