FileWriter 以某种方式用中文写
FileWriter somehow write in chinese
请帮我解决这个问题。我正在尝试编写一个读取 .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 的新手,所以非常感谢您的帮助。
更改此行
fw.write(((char)(i + 'A')) + ": " + count[i]);
至
fw.write(" "+((char)(i + 'A')) + ": " + count[i]);
虽然您的程序有一些可以改进的地方,但其中 none 是您看到汉字的原因。事实上,您的程序似乎运行良好,生成的文件实际上包含您在使用 System.out.println
.
尝试时看到的文本
我已经复制了您的输出示例,使用记事本将其粘贴到一个新文件中,保存后,使用 HEX 编辑器(此处为 HxD)查看了该文件。十六进制数据是这样开始的:FF FE 41 3A 20 31 35 42... "translates" 到 ÿþA: 15B...
。这正是您的预期结果加上记事本在保存文件时创建的 BOM(字节顺序标记),因此不是原始数据的一部分。
那么为什么你会看到奇怪的结果?原因不是您的程序,而是您使用的文本查看器。如果文件缺少 BOM,其中许多尝试进行有根据的猜测,以决定(在 Windows 记事本的情况下)是否应使用 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");
或者使用包含 BOM 的字符集写入文件,例如UTF-8 或 UTF-16。使用 Java 11,您可以直接使用 FileWriter
来实现(有一个新的构造函数可以设置它),如果您必须使用旧版本的 Java,则需要使用OutputStreamWriter
:
OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(file2), "UTF8");
此外:如果 "Open File" 对话框允许您明确指定字符集,请检查您的文本查看器,德语 Windows 系统上的记事本会调用选项 "Codierung" 和 "ANSI" 是 "cp1252"(你的 Java 虚拟机在使用没有特定字符集的 FileWriter
时应该使用的字符集)。
请帮我解决这个问题。我正在尝试编写一个读取 .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 的新手,所以非常感谢您的帮助。
更改此行 fw.write(((char)(i + 'A')) + ": " + count[i]);
至
fw.write(" "+((char)(i + 'A')) + ": " + count[i]);
虽然您的程序有一些可以改进的地方,但其中 none 是您看到汉字的原因。事实上,您的程序似乎运行良好,生成的文件实际上包含您在使用 System.out.println
.
我已经复制了您的输出示例,使用记事本将其粘贴到一个新文件中,保存后,使用 HEX 编辑器(此处为 HxD)查看了该文件。十六进制数据是这样开始的:FF FE 41 3A 20 31 35 42... "translates" 到 ÿþA: 15B...
。这正是您的预期结果加上记事本在保存文件时创建的 BOM(字节顺序标记),因此不是原始数据的一部分。
那么为什么你会看到奇怪的结果?原因不是您的程序,而是您使用的文本查看器。如果文件缺少 BOM,其中许多尝试进行有根据的猜测,以决定(在 Windows 记事本的情况下)是否应使用 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");
或者使用包含 BOM 的字符集写入文件,例如UTF-8 或 UTF-16。使用 Java 11,您可以直接使用 FileWriter
来实现(有一个新的构造函数可以设置它),如果您必须使用旧版本的 Java,则需要使用OutputStreamWriter
:
OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(file2), "UTF8");
此外:如果 "Open File" 对话框允许您明确指定字符集,请检查您的文本查看器,德语 Windows 系统上的记事本会调用选项 "Codierung" 和 "ANSI" 是 "cp1252"(你的 Java 虚拟机在使用没有特定字符集的 FileWriter
时应该使用的字符集)。