Почему Java BufferedReader() неправильно считывает арабские и китайские символы?
Вопрос
Я пытаюсь прочитать файл, который содержит английские и арабские символы в каждой строке, и другой файл, который содержит английские и китайские символы в каждой строке.Однако символы арабского и китайского языков отображаются неправильно - они просто отображаются в виде вопросительных знаков.Есть какие-нибудь идеи, как я могу решить эту проблему?
Вот код, который я использую для чтения:
try {
String sCurrentLine;
BufferedReader br = new BufferedReader(new FileReader(directionOfTargetFile));
int counter = 0;
while ((sCurrentLine = br.readLine()) != null) {
String lineFixedHolder = converter.fixParsedParagraph(sCurrentLine);
System.out.println("The line number "+ counter
+ " contain : " + sCurrentLine);
counter++;
}
}
Выпуск 01
Прочитав строку и получив арабское и китайское слова, я использую функцию для их перевода, просто выполнив поиск Приведенный Текст на арабском языке в ArrayList (который содержит все ожидаемые слова) (используя indexOf();способ).Затем, когда индекс слова найден, он используется для вызова английского слова, которое имеет тот же индекс в другом Arraylist.Однако этот поиск всегда возвращает false, потому что он завершается неудачей при поиске вопросительных знаков вместо арабских и китайских символов.Итак, мой System.out.println print показывает мне нули, по одному за каждый сбой перевода.
* Я использую Netbeans 6.8 Mac версии IDE
Выпуск 02
Вот код, который выполняет поиск перевода:
int testColor = dbColorArb.indexOf(wordToTranslate);
int testBrand = -1;
if ( testColor != -1 ) {
String result = (String)dbColorEng.get(testColor);
return result;
} else {
testBrand = dbBrandArb.indexOf(wordToTranslate);
}
//System.out.println ("The testBrand is : " + testBrand);
if ( testBrand != -1 ) {
String result = (String)dbBrandEng.get(testBrand);
return result;
} else {
//System.out.println ("The first null");
return null;
}
На самом деле я ищу 2 списка массивов, которые могли бы содержать нужное слово для перевода.Если ему не удается найти их в обоих списках массивов, то возвращается значение null.
Выпуск 03
Когда я выполнял отладку, я обнаружил, что считываемые строки сохраняются в моей строковой переменной следующим образом:
"3;0000000000;0000001001;1996-06-22;;2010-01-27;����;;01989;������;"
Выпуск 03
Файл, который я читаю, был предоставлен мне после того, как он был изменен другой программой (о которой я ничего не знаю, кроме того, что она создана на VB), программа изменила арабские буквы, которые отображаются некорректно.Когда я проверил кодировку файла в Notepad ++, он показал, что это ANSI.однако, когда я конвертирую его в UTF8 (который заменил арабскую букву другой английской), а затем конвертирую его обратно в ANSI, арабский язык становится вопросительным знаком!
Решение
Удобный класс для чтения символьных файлов.Конструкторы этого класса предполагают, что кодировка символов по умолчанию и размер байтового буфера по умолчанию являются подходящими.Чтобы указать эти значения самостоятельно, создайте InputStreamReader в FileInputStream.
Итак:
Reader reader = new InputStreamReader(new FileInputStream(fileName), "utf-8");
BufferedReader br = new BufferedReader(reader);
Если это все еще не работает, то, возможно, ваша консоль не настроена на правильное отображение символов UTF-8.Конфигурация зависит от используемой IDE и довольно проста.
Обновить : В приведенном выше коде замените utf-8
с cp1256
.У меня это отлично работает (WinXP, JDK6)
Но я бы рекомендовал вам настаивать на том, чтобы файл был сгенерирован с использованием UTF-8.Потому что cp1256
не сработает для китайцев, и у вас снова возникнут подобные проблемы.
Другие советы
Скорее всего, он правильно считывает информацию, однако ваш выходной поток, вероятно, не является UTF-8, и поэтому любой символ, который не может быть показан в вашем выходном наборе символов, заменяется на '?'.
Вы можете подтвердить это, выведя каждый символ и напечатав порядковый номер символа.
public void writeTiFile(String fileName,String str){
try {
FileOutputStream out = new FileOutputStream(fileName);
out.write(str.getBytes("windows-1256"));
} catch (Exception ex) {
ex.printStackTrace();
}
}