繁体   English   中英

Java:向文件写入/读取字符会产生不同的结果

[英]Java: Writing/Reading a char to a file yields different results

我试图将一个简单的字符写到文件中并读回。将字符写到文件中似乎可以正常工作(至少就像在十六进制编辑器中一样)。 当我将字符读回内存时,它的值完全不同。 这是我的示例代码:

public class myclass {

public static void main(String[] args) {
      char myChar = 158; // let myChar = 158

      System.out.println("myChar = "+(int)myChar); // prints 158. Good.   

        try {
            FileOutputStream fileOut = new FileOutputStream("readthis");
                fileOut.write(myChar);
            fileOut.close();
        } catch (IOException e) {
            System.exit(1);
        }


        // If I examine the "readthis" file, there is one byte that has a value of
        // of '9E' or 158. This is what I'd expect.   

        // Lets try to now read it back into memory   


        char readChar = 0;

        try {
            int i = 0;

            FileInputStream fstream = new FileInputStream("readthis");
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));

                readChar = (char)br.read();                     


            in.close();

        } catch (IOException e) {
            System.exit(1);
        }

        // Now, if we look at readChar, it's some value that's not 158!
        // Somehow it got read into as 382!   

        // Printing this value results in 382
        System.out.println("readChar = "+(int)readChar);




  }

}

我的问题是,这是怎么发生的? 我希望readChar等于我写的原始值(158),但是我不确定自己做错了什么。 任何帮助,将不胜感激。 谢谢。

您正在写字节并读取字符。 使用WriterReaderOutputStreamInputStream

EJP是正确的。 较长的解释:字符具有两个属性,而您忽略了一个:编码。

这意味着char myChar = 158myChar分配了Unicode代码点158(这不是Unicode中的可打印字符)。

当你写一个文件的字节(使用fileOut.write(int)你的Unicode字符转换为整数158 -编码丢失。 write()方法将从整数中去除除低8位以外的任何内容( write(158+256)产生与write(158)相同的结果)。

当您再次读入数据时,您使用的是Reader ,该读取Reader读取字节并将其转换为Unicode字符。 为正确执行此操作,您需要指定用于写入数据的编码。 由于您未明确指定任何内容,因此Java使用平台默认编码(操作系统的默认编码)。

因此,阅读器读取158 ,并使用默认编码将其转换为char

要解决此问题,请始终与Reader / Writer以及InputStreamReaderOutputStreamWriter一起使用,后者允许您指定要使用的编码。 UTF-8是一个不错的选择,因为所有Java VM都可以读取它们,并且所有Unicode字符都可以转换为该编码或从该编码转换。

如果只想写/读字符,请尝试使用DataOutputStream#writeChar()DataInputStream#readChar() ,但是InputStreamRead / OutputStreamWriter更为灵活。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM