我正在尝试将一个简单的字符写入文件并将其重新读入。将字符写入文件似乎工作正常(至少在十六进制编辑器中显示)。当我将角色重新读回内存时,它完全是一个完全不同的价值。这是我的示例代码:
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),但我不确定我做错了什么。任何帮助,将不胜感激。感谢。
答案 0 :(得分:5)
您正在编写字节和读取字符。使用Writer
和Reader
,或OutputStream
和InputStream
。
答案 1 :(得分:3)
EJP是对的。更长的解释:角色有两个属性,你省略了一个:编码。
这意味着char myChar = 158
分配myChar
Unicode代码点158(这不是Unicode中的可打印字符)。
当您将该文件作为字节写入文件时(使用fileOut.write(int)
),您将Unicode字符转换为整数158
- 编码将丢失。 write()
方法将除去整数中的低8位(write(158+256)
产生与write(158)
相同的结果)。
当您再次读取数据时,您正在使用Reader
读取字节并将其转换为Unicode字符。要正确执行此操作,您需要指定用于编写数据的编码。由于您没有明确指定任何内容,因此Java使用平台默认编码(操作系统的默认编码)。
读者阅读158
,并使用默认编码将其转换为char
。
要解决此问题,请始终使用Reader
/ Writer
以及InputStreamReader
和OutputStreamWriter
,以便指定要使用的编码。 UTF-8
是一个不错的选择,因为所有Java VM都可以读取它们,所有Unicode字符都可以转换为此编码。
答案 2 :(得分:1)
如果您只想写/读字符,请尝试DataOutputStream#writeChar()
和DataInputStream#readChar()
,但InputStreamRead / OutputStreamWriter更灵活。