1.关于RandomAccessFile的write(int b)
为了这个问题,花掉了大半个下午的时间,只怪自己没有仔细看文档。
import java.io.*;
public class Demo {
public static void main(String[] args) throws Exception {
RandomAccessFile raf = new RandomAccessFile("demo.txt","rw");
raf.write(97);
}
}
今天,复习到RandomAccessFile这个类,
其中毕老师提出过一个问题,“write(int b)与writeInt(int v)的区别”,
经过上机我发现write(int b)写入97后,记事本打开显示的是'a'字符,
之前看视频没有仔细想,现在发现确实很难理解为什么会有这种情况。
public native void write(int b) throws IOException;
通过Eclipse查看源码,发现这个write方法是一个native方法,
API文档则说:"向此文件写入指定的字节。从当前文件指针开始写入。"
还是不能解释为什么会这样。
可是,我却忽略了文档中的一句 —— 指定者:接口 DataOutput 中的 write。
接口 DataOutput 中的 write(int b),会将参数b
的八个低位写入输出流。忽略b
的 24 个高位。
也就是int类型97只剩下低八位的1100001,记事本再按ASCII码表查表后,就是'a'了。
2.Writer的write(int c)
API解释:
写入单个字符。
要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。
用于支持高效单字符输出的子类应重写此方法。
import java.io.*;
public class Demo {
public static void main(String[] args) throws Exception {
PrintWriter pw = new PrintWriter("demo.txt");
pw.write(97);
pw.write('a');
pw.close();
System.out.println(Integer.toBinaryString(97));//1100001
Character a = 'a';
System.out.println(a.SIZE);//16
System.out.println(charToByte2(a)[0]+" "+charToByte2(a)[1]);//0 97
}
public static byte[] charToByte2(char c) {
byte[] arr = new byte[2];
arr[0] = (byte) ((c >> 8)& 0xff);
arr[1] = (byte) (c & 0xff);
return arr;
}
}
从上面的程序可以看出,'a'的低八位跟97的二进制表示是一样的。
public void write(int c) throws IOException {
synchronized (lock) {
if (writeBuffer == null){
writeBuffer = new char[writeBufferSize];
}
writeBuffer[0] = (char) c;
write(writeBuffer, 0, 1);
}
}
上面是方法的源码,其实就是把这个int c当成了(char)c来处理了。
这个方法平时做题很少用到,没想到里面还有这般学问。
参考资料:java.io菜鸟问题