FileWriter как-то пишу по-китайски - PullRequest
4 голосов
/ 22 октября 2019

Пожалуйста, помогите мне с этой проблемой. Я пытаюсь написать код, который читает файл .txt, а затем он будет считать частоты каждой буквы в файле. Вот что я придумал:

public static void charCount(String file) throws IOException {
        FileReader fr = new FileReader(file);
        BufferedReader br = new BufferedReader(fr);

        int[] count = new int[26];
        String line;
        while ((line = br.readLine()) != null) {
            line = line.toUpperCase();
            char[] characters = line.toCharArray();
            for (int i = 0; i < line.length(); i++) {
                if ((characters[i] >='A') && (characters[i] <='Z')) {
                    count[characters[i] - 'A']++;
                }
            }
        }
        File file2 = new File("D:/Project/Aufgabe/Winter_2019/frequency.txt");
        file2.createNewFile();
        FileWriter fw = new FileWriter(file2);
        for (int i = 0; i < 26; i++) {
            fw.write(((char)(i + 'A')) + ": " + count[i]);
        }
        fw.close();
        br.close();
    }

Когда я пытался распечатать результат в консоли с помощью System.out.println (), он выдает следующие результаты:

A: 15
B: 4
C: 9
D: 10
E: 2
F: 1
G: 0
H: 3
I: 5
J: 6
K: 3
L: 0
M: 2
N: 7
O: 3
P: 1
Q: 1
R: 0
S: 4
T: 0
U: 2
V: 0
W: 5
X: 0
Y: 1
Z: 0

Что я и хочу. Но когда я попытался записать его в файл, он выдает следующие результаты в файле .txt:

㩁ㄠ䈵›䌴›䐹›〱㩅㈠㩆ㄠ㩇〠㩈㌠㩉㔠㩊㘠㩋㌠㩌〠㩍㈠㩎㜠㩏㌠㩐ㄠ㩑ㄠ㩒〠㩓㐠㩔〠㩕㈠㩖〠㩗㔠㩘〠㩙ㄠ㩚〠

Я все еще новичок в Java, поэтому помощь будет очень признательна.

Ответы [ 3 ]

5 голосов
/ 22 октября 2019

Хотя в вашей программе есть несколько вещей, которые можно улучшить, ни одна из них не является причиной, по которой вы видите китайские иероглифы. На самом деле ваша программа, кажется, работает нормально, и полученный файл фактически содержит текст, который вы видели при попытке использовать System.out.println.

. Я скопировал ваш выходной пример, вставил его в новый файл, используяБлокнотом и после сохранения посмотрел файл с помощью HEX-редактора (здесь HxD). Шестнадцатеричные данные начинаются так: FF FE 41 3A 20 31 35 42 ... который "переводит" в ÿþA: 15B.... Это именно ваш ожидаемый результат плюс спецификация байта (Byte Order Marker), которая была создана Notepad при сохранении файла и поэтому не является частью исходных данных.

Так почему вы видите странный результат? Причина - не ваша программа, а средство просмотра текста, которое вы используете. Многие из них пытаются сделать обоснованное предположение, если файл пропускает спецификацию, чтобы решить, следует ли (в случае Windows Notepad) файл читать с cp1252 (Windows Latin-1), UTF-8 или Unicode / UTF-16. Существуют разные алгоритмы, поэтому трудно сказать, почему ваш зритель решил, что это может быть UTF-16, но это так; -)

У меня есть предположение, и решение вашей проблемы может заключаться в изменении

fw.write(((char)(i + 'A')) + ": " + count[i]);

до

fw.write(((char)(i + 'A')) + ": " + count[i] + "\r\n");

В качестве альтернативы запишите файл, используя набор символов, который включает в себя спецификацию, например, UTF-8 или UTF-16. С Java 11 вы можете сделать это непосредственно с FileWriter (есть новый конструктор, который позволяет установить это), если вам нужно использовать более старую версию Java, вам нужно использовать OutputStreamWriter:

OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(file2), "UTF8");

Также: проверьте средство просмотра текста, если -диалог «Открыть файл» позволяет вам явно указать Charset, Notepad в немецкой системе Windows вызывает опцию «Codierung», а «ANSI» - это «cp1252» (кодировка вашего Java)Виртуальная машина должна была использоваться при использовании FileWriter без определенной кодировки).

1 голос
/ 22 октября 2019

Решение так же просто, как настроить ваш fw.write следующим образом:

for (int i = 0; i < 26; i++) {
    fw.write(((char)(i + 'A')) + ": " + String.valueOf(count[i])+"\n");
}

Я уже протестировал его, и вы можете уверенно его использовать.

Я также протестировал следующееспособы правильной работы:

for (int i = 0; i < 26; i++) {
    fw.write(((char)(i + 'A')) + ": " + count[i]+" \n");
}

или

for (int i = 0; i < 26; i++) {
    fw.write(((char)(i + 'A')) + ": " + new Integer(count[i]).toString()+"\n");
}
0 голосов
/ 22 октября 2019

Изменить эту строку fw.write (((char) (i + 'A')) + ":" + count [i]);

на

fw.write ("" + ((символ) (i + 'A')) + ":" + count [i]);

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...