Intellij Idea 阅读使用utf-8编码的文件不起作用,但阅读使用“windows-1252”或“iso-8859-1”的相同文件起作用

zaq34kh6  于 2023-11-16  发布在  Windows
关注(0)|答案(3)|浏览(203)

这里发生了什么?为什么当我使用utf-8读取文件时,它会在控制台中输出问号?
这是一个最小的工作示例:
x1c 0d1x的数据

  1. import java.io.File;
  2. import java.io.IOException;
  3. import java.nio.charset.Charset;
  4. import static org.apache.commons.io.FileUtils.readFileToString;
  5. import static org.apache.commons.io.FileUtils.writeStringToFile;
  6. public class Main {
  7. public static void main(String... args) throws IOException {
  8. System.out.println("---------");
  9. System.out.println(Charset.defaultCharset());
  10. System.out.println("æ ø å");
  11. System.out.println("æ ø å");
  12. System.out.println("æ ø å");
  13. File inputFile = new File(System.getProperty("user.dir") + "/input.md");
  14. File outputFile = new File(System.getProperty("user.dir") + "/output.md");
  15. String content, encoding;
  16. System.out.println("--------- windows-1252");
  17. encoding = "windows-1252";
  18. content = readFileToString(inputFile, encoding);
  19. System.out.println(content);
  20. System.out.println("--------- iso-8859-1");
  21. encoding = "iso-8859-1";
  22. content = readFileToString(inputFile, encoding);
  23. System.out.println(content);
  24. System.out.println("--------- utf-8");
  25. encoding = "utf-8";
  26. content = readFileToString(inputFile, encoding);
  27. System.out.println(content);
  28. writeStringToFile(outputFile, content, encoding);
  29. }
  30. }

字符串
其中input.md包含:(以UTF-8编码)

  1. This is input.md. 'æ' 'ø' 'å'


运行上面的代码会产生

  1. ---------
  2. windows-1252
  3. æ ø å
  4. æ ø å
  5. æ ø å
  6. --------- windows-1252
  7. This is file C. 'æ' 'ø' 'å'.
  8. --------- iso-8859-1
  9. This is file C. 'æ' 'ø' 'å'.
  10. --------- utf-8
  11. This is file C. '�' '�' '�'.

为什么当我用UTF-8读取文件时会得到?这特别奇怪,因为文件是用UTF-8编码的
UPDATE:我的控制台设置为UTF-8:



下面是从输入文件中提取的字符串中每个字符的十六进制值的屏幕截图:



下面是一个更好的隔离十六进制的屏幕截图:


yhuiod9q

yhuiod9q1#

代码看起来没问题,output.md文件看起来也没问题。所以这很可能只是控制台输出的问题。
您正在试验的Unicode字符在Windows-1252和ISO-8859-1中编码为相同的单个字节(æ = 0xE6ø = 0xF8å = 0xE5),但在UTF-8中编码为多个字节(æ = 0xC3 0xA6ø = 0xC3 0xB8å = 0xC3 0xA5)。
阅读一个UTF-8编码的文件,无论是Windows-1252还是ISO-8859-1,都会单独解码每个字节,产生一个string,每个字节包含一个单独的char,而这些char将具有与字节相同的数值。所以,你应该得到一个string,包含0x00C3 0x00A60x00C3 0x00B8,和0x00C3 0x00A5。将这些char输出到控制台作为Windows-1252 * 应该 * 显示为æ ø Ã¥,而不是æ ø å
另一方面,阅读UTF-8编码的文件作为UTF-8将正确解码文件,生成string,其中包含char0x00E60x00F80x00E5。将string写入UTF-8编码的文件应生成正确的字节序列(0xC3 0xA60xC3 0xB80xC3 0xA5),但输出与Windows-1252相同的string会有数据丢失的风险,但您 * 应该 * 会看到预期的æ ø å,因为Windows-1252确实支持这些Unicode字符。
所以,你的结果实际上是从我所期望的倒退。即使Charset.defaultCharset()报告的是Windows-1252,我怀疑你的控制台实际上是使用不同的字符集为它的输出。
我建议你打印出content字符串中每个char的数值,看看input.md实际上是如何被每种编码解码的。你应该得到我上面提到的char值。

jckbn6z7

jckbn6z72#

对于有类似问题的人来说,问题在于控制台的编码(正如@雷米勒博也指出的那样)。
我通过遵循此answer解决了此问题
事实上,我在评论中关注了@Nicolas的回答,并提到了回答:
这也可以从帮助>编辑自定义VM选项.然后重新启动IntelliJ.我真的尝试了一切:在IntelliJ中更改编码设置,更改属性文件设置的JVM选项,build.gradle文件,IntelliJ,运行配置,环境变量等。还尝试更改系统范围的编码,但没有任何效果,除了这个
现在我得到了预期的输出:
x1c 0d1x的数据

piv4azn7

piv4azn73#

我遇到了一个类似的问题,我发现我的系统上的 * 一些 * JDK产生了Cp1252file.encoding,而不是UTF-8。我不知道为什么。
然后,您可以添加-Dfile.encoding=UTF-8,或者如果您使用Gradle,则可以将org.gradle.jvmargs=-Dfile.encoding=UTF-8添加到~/.gradle/gradle.properties%userprofile%\.gradle\gradle.properties)或在项目级别添加到gradle.properties
或者尝试使用所需的file.encoding重新安装JDK。

相关问题