在Java中将UTF-8文本文件读取为UTF-16

use*_*837 -4 java encoding utf-8 utf-16 character-encoding

我正在 Java 程序中将 UTF-8 编码的文本文件读取为 UTF-16,只是为了看看会发生什么。我得到的输出字符串仅包含“?”。谁能解释一下 UTF-8 代码点如何转换为 UTF-16 以及为什么我只得到“?” 在我的输出中。

这是代码-

public class MyUTF {

    public static void main(String[] args)
        throws IOException, FileNotFoundException
    {
        InputStream is=new FileInputStream("file1.txt");
        System.out.println(is.available());

        InputStreamReader isr=new InputStreamReader(is,"UTF-16");
        BufferedReader br=new BufferedReader(isr);
        System.out.println(br.readLine());
    }
}
Run Code Online (Sandbox Code Playgroud)

如果文件包含“a”,那么我会得到“?” 作为输出。如果它包含“abc”,那么我会得到“??”。

请解释一下从 UTF-8 到 UTF-16 的转换。

提前致谢。

Ray*_*oal 5

您在终端中看到的内容取决于许多因素:

\n\n
    \n
  • 您的平台是小端还是大端?
  • \n
  • 您的终端可以显示很多字符还是只显示几个字符?
  • \n
\n\n

如果您只看到问号,则您可能拥有一台旧计算机或一个非常糟糕的终端仿真器。

\n\n

我可以告诉你我在 Mac 上看到的内容。我的笔记本电脑是小端字节序。我让文件file1.txt包含abc一个新行。换句话说,四个字符U+0061 U+0062 U+0063 U+000A。现在,由于 UTF-8 是默认编码,我的文件包含 4 个字节:

\n\n
61 62 63 0A\n
Run Code Online (Sandbox Code Playgroud)\n\n

请理解文件仅包含字节。它不包含字符。(当然有一些技巧,比如在文件中粘贴 BOM 以使文件\xe2\x80\x99s 的预期编码显而易见,但实际上这只是一个建议。)

\n\n

现在,当您以 UTF-16 形式读取该文件时,您就解码了将这四个字节

\n\n
U+6162\nU+630A\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我运行你的程序时,它会像这样打印

\n\n
\xe6\x85\xa2\xe6\x8c\x8a\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在假设我没有换行符,因此文件只有三个字节。在这种情况下

\n\n
61 62 63\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在当我运行你的程序时我看到

\n\n
\xe6\x85\xa2\xef\xbf\xbd\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是之前的字符 U+6162 ,然后是替换字符,因为您无法解码 UTF-16 中的单字节 63。在 UTF-16 中,字符以 2 或 4 个字节表示,而不仅仅是 1。我的终端程序显示替换字符。我认为你的只是显示问号。

\n