Java:BufferedReader 在转换为 Char 时将值 128-159 继续写入 63

Java: BufferedReader Keeps Writing Values 128-159 as 63 When Converting to Char

我正在尝试编写一个十六进制编辑器。我试图通过将字符写入文本文件来存储值。出于某种原因,每个十进制数 128-159 都被写入或读取(不确定是哪个)为 63。我采取措施隔离问题。这是一个发生的例子:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;

public class Why {

    public static File file = new File("why.txt");

    public static void main(String[] args) throws IOException {
        if(!file.exists())
            file.createNewFile();

        BufferedWriter bw = new BufferedWriter(new FileWriter(file));
        bw.write((char) 144);
        bw.close();

        BufferedReader br = new BufferedReader(new FileReader(file));
        System.out.println(br.read());
        br.close();
    }
}

感谢任何帮助。

我使用 FileOutputStream 和 FileInputStream 解决了这个问题。谢谢大家

字符 63 是 ?,这意味着您使用的编码不支持您尝试写入的字符(并将其替换为 ?)。

这是您应该暂时停止使用十六进制编辑器并了解字符编码的神奇(和可怕)世界的部分,以及为什么您不能忽略它们。

这是一篇很棒的读物The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!),它仍然和 2003 年一样有效。

当您使用 FileReaderFileWriter 时,它们将使用您平台的默认编码。这几乎总是一个坏主意。

在您的情况下,该编码似乎不支持 U+0092,这是相当合理的,因为它是一个私人使用的字符 - 许多编码都不支持它。我怀疑您 实际上 根本不想要 (char) 144。如果您真的非常想使用该字符,您应该使用可以对所有 Unicode 进行编码的编码 - 我建议使用 UTF-8。

区分文本和二进制很重要,但是 - 如果您真的只对 字节 感兴趣,那么您不应该使用 reader 或 writer完全 - 使用 InputStreamOutputStream。十六进制编辑器通常是面向字节的而不是面向文本的,尽管它们也可以提供文本视图(理想情况下具有可配置的编码)。如果你想知道文件中的确切字节,你绝对应该使用 FileInputStream.