簡體   English   中英

Java的字符集/字符編碼

[英]Java's charsets / character encoding

我有一個西班牙文件,所以它充滿了以下字符:

 á é í ó ú ñ Ñ Á É Í Ó Ú 

我必須閱讀該文件,所以我這樣做:

fr = new FileReader(ficheroEntrada);
BufferedReader rEntrada = new BufferedReader(fr);

String linea = rEntrada.readLine();
if (linea == null) {
logger.error("ERROR: Empty file.");
return null;
} 
String delimitador = "[;]";
String[] tokens = null;

List<String> token = new ArrayList<String>();
while ((linea = rEntrada.readLine()) != null) {
    // Some parsing specific to my file. 
    tokens = linea.split(delimitador);
    token.add(tokens[0]);
    token.add(tokens[1]);
}
logger.info("List of tokens: " + token);
return token;

當我讀取令牌列表時,所有特殊字符都消失了,並被這種字符替換:

Ó = Ó
Ñ = Ñ

等等...

發生了什么? 我從未遇到過charsets的問題(我假設是charset問題)。 是因為這台電腦嗎? 我能做什么?

任何額外的建議將不勝感激,我正在學習! 謝謝!

您需要指定相關的字符編碼。

BufferedReader rEntrada  = new BufferedReader(
    new InputStreamReader(new FileInputStream(fr), "UTF-8"));

發生了什么?

建議使用UTF-8編碼進行讀寫的答案應該可以解決您的問題。 我的答案更多的是關於將來發生的事情以及如何診斷類似的問題。

首先是http://www.utf8-chartable.de上的UTF-8字符表。 頁面上有一個下拉菜單,可讓您瀏覽Unicode的不同部分。 你的一個問題是Ó 檢查圖表顯示,如果你的文件是用UTF-8編碼的,那么字符是U+00D3 LATIN CAPITAL LETTER O WITH ACUTE ,UTF-8序列是兩個字節,hex c3 93

現在讓我們檢查一下http://en.wikipedia.org/wiki/ISO/IEC_8859-1上的ISO-8859-1字符集,因為這也是一個流行的字符集。 然而,這是那些單字節字符集之一。 每個有效字符由單個字節表示,與UTF-8不同,其中字符可以由1,2或3個字節表示。

請注意,C3處的字符看起來像Ã但93處沒有字符。所以您的默認編碼可能不是ISO-8859-1。

接下來,請訪問http://en.wikipedia.org/wiki/Windows-1252查看Windows 1252。 這幾乎與ISO-8859-1相同,但用一些有用的字符填充一些空格。 我們有一場比賽。 Windows 1252中的序列C3 93正好是字符串Ó

這一切告訴我的是,您的文件是UTF-8編碼的,但您的Java環境配置了Windows 1252,因為它是默認編碼。 如果修改代碼以顯式指定字符集(“UTF-8”)而不是使用默認值,則代碼在不同環境中失敗的可能性會降低。

請記住 - 這可能就像其他方式一樣容易發生。 如果您有一個主要是西班牙文本的文件,它可以很容易地成為ISO-8859-1或Windows 1252編碼文件。 在這種情況下,在您的機器上運行的代碼可以正常運行並將其切換為“UTF-8”編碼會創建一組不同的亂碼。

這是您獲得相互矛盾的建議的部分原因。 不同的人基於他們的平台遇到了不同的不匹配,因此發現了不同的修復。

如果有疑問,我在emacs中讀取文件並切換到hexl-mode,這樣我就可以在文件中看到確切的二進制數據。 我相信有更好,更現代的方法來做到這一點。

最后的想法 - 可能值得閱讀絕對最低每個軟件開發人員,絕對必須知道Unicode和字符集(沒有借口!

您的默認編碼錯誤。 您可能需要閱讀UTF8或latin1。 請參閱此代碼段以在流上設置編碼。 另請參見Java,默認編碼

public class Program {

    public static void main(String... args)  {

        if (args.length != 2) {
            return ;
        }

        try {
            Reader reader = new InputStreamReader(
                        new FileInputStream(args[0]),"UTF-8");
            BufferedReader fin = new BufferedReader(reader);
            Writer writer = new OutputStreamWriter(
                       new FileOutputStream(args[1]), "UTF-8");
            BufferedWriter fout = new BufferedWriter(writer);
            String s;
            while ((s=fin.readLine())!=null) {
                fout.write(s);
                fout.newLine();
            }

            //Remember to call close. 
            //calling close on a BufferedReader/BufferedWriter 
            // will automatically call close on its underlying stream 
            fin.close();
            fout.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

根據我的經驗,文本文件應該基於西方編碼來讀寫:ISO-8859-1。

BufferedReader rEntrada = new BufferedReader(new InputStreamReader(new FileInputStream(fr),“ISO-8859-1”));

其他答案為您提供了正確的方向。 只想添加Guava及其Files.newReader(File,Charset)幫助器方法使得創建這樣一個BufferedReader很多可讀(請原諒雙關語):

BufferedReader rEntrada = Files.newReader(new File(ficheroEntrada), Charsets.UTF_8);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM