Чтение странного символа юникода в Java? - PullRequest
4 голосов
/ 27 марта 2012

У меня есть следующий текстовый файл:

enter image description here

Файл был сохранен в кодировке utf-8.

Я использовал следующий код для чтения содержимого файла:

FileReader fr = new FileReader("f.txt");
BufferedReader br = new BufferedReader(fr);
String s1 = br.readLine();
String s2 = br.readLine();
System.out.println("s1 = " + s1.length());
System.out.println("s2 = " + s2.length());

вывод:

s1 = 5

s2 = 4

Затем я попытался использовать s1.charAt(0);, чтобы получить первый символ s1, и это был '' (пустой) символ. Вот почему s1 имеет длину 5. Даже если я попытался использовать s1.trim();, его длина все равно 5. Я не знаю, почему это произошло? Он работал правильно, если файл был сохранен в кодировке ASCII.

Ответы [ 5 ]

7 голосов
/ 27 марта 2012

Блокнот, очевидно, сохранил файл с меткой порядка байтов , непечатаемым символом в начале, который просто помечает его как UTF-8, но не является обязательным (и даже не рекомендуемым) для использования.Вы можете игнорировать или удалить его;другие текстовые редакторы часто предоставляют вам выбор использования UTF-8 с или без спецификации.

1 голос
/ 27 марта 2012

Что ж, вы можете пытаться прочитать ваш файл, используя другую кодировку.

Вам необходимо использовать класс OutputStreamReader в качестве параметра считывателя для вашего BufferedReader.Он принимает кодировку.Просмотрите Java Docs .

Примерно так:

BufeferedReader out = new BufferedReader(new OutputStreamReader(new FileInputStream("jedis.txt),"UTF-8")))

Или вы можете установить текущую системную кодировку с системным свойством file.encoding в UTF-8.

java -Dfile.encoding=UTF-8 com.jediacademy.Runner arg1 arg2 ...

Вы также можете установить его как системное свойство во время выполнения с System.setProperty(...), если оно понадобится только для этого конкретного файла, но в таком случае, как я думаю, я бы предпочел OutputStreamWriter.

Установив системное свойство, вы можете использовать FileReader и ожидать, что оно будет использовать UTF-8 в качестве кодировки по умолчанию для ваших файлов.В этом случае для всех файлов, которые вы читаете и записываете.

Если вы намерены обнаруживать ошибки декодирования в вашем файле, вам придется использовать подход OutputStreamReader и использовать конструктор, который получает декодер.

В некотором роде

CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
decoder.onMalformedInput(CodingErrorAction.REPORT);
decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
BufeferedReader out = new BufferedReader(new InputStreamReader(new FileInputStream("jedis.txt),decoder));

Вы можете выбирать между действиями IGNORE | REPLACE | REPORT

1 голос
/ 27 марта 2012

На самом деле это не пустой символ, это спецификация - Порядок следования байтов . Windows использует спецификацию для маркировки файлов как файлов в кодировке Unicode (UTF-8, UTF-16 и UTF-32).

Я думаю вы можете сохранять файлы без спецификации даже в Блокноте (на самом деле это не требуется).

0 голосов
/ 27 марта 2012

Даже если я попытался использовать s1.trim ();его длина все еще 5.

Я ожидаю, что вы делаете это:

    s1.trim();

Это не делает то, что вы хотите, чтобы он делал.Строки Java являются неизменяемыми, а метод trim() создает новую строку ... которую вы затем выбрасываете.Вам нужно сделать это:

    s1 = s1.trim();

..., который назначает ссылку на новую строку, созданную trim(), для того, чтобы вы могли ее использовать.

(Примечание: trim() не всегда создает новую строку. Если исходная строка не имеет начальных или конечных пробелов, метод trim() просто возвращает ее как есть.)

0 голосов
/ 27 марта 2012

нулевой символ, например.когда вы используете (char) 0, переводится как ''

. Возможно, что программа чтения файлов читает нулевой символ в начале файла.Хотя я не уверен, почему ...

...