2011-12-23 60 views
5

控制檯輸入(win),charset轉換是如何工作的?java控制檯字符集轉換

下面的代碼,非ASCII字符輸出垃圾 - 以下示例中的InputStreamReader不會將字符集作爲參數。

BufferedReader console = new BufferedReader(new InputStreamReader(System.in)); 
String inp = console.readLine(); 
System.out.println(inp.toUpperCase()); 

作爲獨立於操作系統的,如何解決Java的關於控制檯提示符下輸入的所有不同的可能的字符集的配置?

回答

12

其實,Java並不在所有處理這個問題。

它只是假定控制檯編碼與系統默認編碼相同。 This assumption is wrong on Windows systems,因此對於Windows上的非ascii字符,Java不提供正確的控制檯IO的良好解決方案。

可能的解決方案是:

  • 使用System.console() Java 6中介紹:

    BufferedReader in = new BufferedReader(System.console().reader()); 
    BufferedWriter out = new PrintWriter(System.console().writer(), true); 
    
    out.println(in.readLine().toUpperCase()); 
    

    注意System.console()可以返回null當你用程序重定向IO運行,例如,在IDE。這種情況需要回退。

  • 明確指定控制檯編碼:

    String consoleEncoding = "..."; 
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in, consoleEncoding)); 
    BufferedWriter out = new PrintWriter(new OutputStreamWriter(System.in, consoleEncoding), true); 
    
    out.println(in.readLine().toUpperCase()); 
    

    據我所知,有沒有什麼好方法來確定實際的控制檯編碼程序沒有本地代碼。

  • 使用file.encoding屬性指定控制檯編碼作爲默認編碼,使該控制檯IO使用默認編碼的假設是正確的:

    java -Dfile.encoding=... ... 
    
5

1)實事求是地講:怎麼辦字符編碼工作,你應該如何對付它們:

是在被編碼/解碼讀取任何字符流。 Java將編碼/解碼細節捆綁爲JDK的一部分:http://docs.oracle.com/javase/1.6/docs/guide/intl/encoding.doc.html。例如:UTF-8 issue in Java code

2)您的具體問題:跨平臺JAVA語言如何處理操作系統特定的控制檯輸入?

簡短回答:儘管Java字節碼是平臺中立的,但JVM並不是。也就是說,java的「System」「in/out/err」流功能​​並沒有在普通的老java中完全實現!

當您運行java時,會加載「System」類,該類抽象了運行JVM的系統的基本概念。在這個時候,它的輸入/輸出/錯誤流是(即你輸入System.in,System.out,System.err時所訪問的對象是由ClassLoader在RUNTIME中設置的,它負責...裝載Java類。

在「系統」的情況下,類加載是一個複雜的任務,因爲你暗示,因爲建立系統類(就像設置Java 運行類)是一個較低的水平JVM的實現問題是特定於操作系統的。

再一次,要清楚的是:雖然Java LANGUAGE是平臺無關的,但是與Java編程語言不同的是, OS特定的環境,它創建我們在運行時爲我們在代碼中引用的資源。

欲瞭解更多信息:查看System類的實際源代碼,它非常易讀,並且會讓您更好地理解正在發生的事情。特別是,看nullInputStream()方法:

http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Core/lang/java/lang/System.java.htm