24. 关于Writer类的write(int c) 方法

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来处理了。

这个方法平时做题很少用到,没想到里面还有这般学问。

参考资料:

经验分享 程序员 微信小程序 职场和发展