Java、Unicode、UTF-8 和 Windows Command Prompt

2022-09-04 02:52:22

我有一个jar文件,它应该读取UTF-8编码的文件 - 我在Windows下的文本编辑器中编写 - 并将字符显示到屏幕上。在OS X和Linux下,这可以完美地工作。我遇到了一些麻烦,让它在Windows下工作虽然...我这样定义了一个读者和作家:

FileInputStream file = new FileInputStream(args[0]);
InputStreamReader reader = new InputStreamReader(file, "UTF8");

PrintStream writer = new PrintStream(System.out, true, "UTF8");

我还按照这个顺序将命令提示符字体更改为 UTF-8,并将字符编码更改为 UTF-8。Lucida Consolechcp 65001

现在,当我跑的时候,提示把它挥霍出来了。java -jar Read.jar file.txt

áéí
ñóú
[]óú
[]

但是,如果我运行 ,则提示会正确显示文件的内容。type file.txt

áéí
ñóú

我尝试过使用和不使用BOM保存文件,但这并没有产生任何影响。(UTF-8 甚至不需要 BOM,因为它缺乏字节序,对吗?我尝试过使用 编译,但同样的事情发生了。javac -encoding utf8 *.java

我现在没有想法了。有人愿意帮忙吗?


答案 1

代码页 65001 已损坏。MS C 运行时 stdio 函数在 65001 下运行时返回读取和写入的不准确的字节数,这会导致像这样的奇怪行为。

它是不可修复的 - 您无法可靠地使用Windows控制台从使用C stdlib字节I / O函数(包括Java)的应用程序进行Unicode I / O。您可以通过调用Win32 API函数W writeConsoleW将Unicode内容直接获取到控制台来破解它,但是这样您就必须担心检测stdout何时实际上是控制台(未重定向到文件)。

这是一个长期存在的灾难来源,MS没有兴趣修复。


答案 2

看起来它可能是你换行符。当我在标准英语ISO-8859-1中制作换行符时,我使用char[]数组,因为Windows字符'\r'和'\n'和UNIX / Linux只有\r作为换行符。Win 4 bytes , unix 2 bytes.在字符转换器类的 API 文档中,编码转换系统可能残留杂散字节,以丢弃依赖于编码和字符大小要求的杂散字节。


推荐