<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 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

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

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

     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(系統默認編碼)
    這個是系統默認編碼,windows英文操作系統是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上執行?

    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
    很好啊
    主站蜘蛛池模板: 国产精品深夜福利免费观看| 成年人视频免费在线观看| 国产精品四虎在线观看免费| 亚洲国产精品免费在线观看| 5555在线播放免费播放| 亚洲性无码av在线| 国产成人午夜精品免费视频| 亚洲一卡2卡3卡4卡国产网站| 免费看片在线观看| 亚洲中文字幕久久无码| 好吊妞视频免费视频| 亚洲精品美女久久7777777| 国产午夜无码视频免费网站| 粉色视频成年免费人15次| 亚洲人成无码www久久久| 少妇性饥渴无码A区免费| 亚洲国产美国国产综合一区二区| 久久福利资源网站免费看| 亚洲精品国产精品国自产网站| 最近中文字幕无免费视频| 青草青草视频2免费观看| 国产AV无码专区亚洲AV漫画| 无码AV片在线观看免费| 亚洲人成电影青青在线播放| 永久免费AV无码网站在线观看| 免费看美女午夜大片| 亚洲AV午夜成人片| 毛片基地免费观看| 午夜免费国产体验区免费的| 亚洲va久久久噜噜噜久久狠狠| 免费可以在线看A∨网站| 男女超爽视频免费播放| 亚洲国产第一站精品蜜芽| 久久久久国色AV免费观看性色| 阿v免费在线观看| 久久亚洲国产成人亚| 天天摸天天操免费播放小视频| 黄视频在线观看免费| 亚洲综合校园春色| 亚洲精品成人片在线观看精品字幕| 四虎1515hh永久久免费|