为何FileOutputStream的write()可写入字符,OutputStreamWriter的write()却无法成功?
为什么FileOutputStream的write()能写入字符,而OutputStreamWriter不行?
兄弟,我来给你把这个事儿掰扯明白!你遇到的问题核心其实和流的类型差异以及资源的正确收尾操作有关,咱一步步拆解:
首先得搞懂两个流的本质:
FileOutputStream是字节流,它的write(int b)方法本质是写字节——你传的'a'对应的ASCII码是97,这个值的低8位就是字节0x61,会直接被写入文件。而且字节流的操作如果是程序正常结束,操作系统通常会自动帮你把残留数据刷入磁盘,所以你能在B.txt里看到内容。OutputStreamWriter是字符流的包装类,它的作用是把字符转换成对应编码的字节,再交给底层的字节流写入。但它内部自带了一个用户态缓冲区!也就是说你调用write('a')的时候,这个字符只是被放到了缓冲区里,根本没立刻写到磁盘上。如果没调用flush()或者close()方法,缓冲区的内容就会一直留在内存里,不会被写入A.txt,所以你打开文件会发现是空的。
你把第一段代码改成这样,就能成功写入了:
OutputStreamWriter ows = new OutputStreamWriter(new FileOutputStream("A.txt")); ows.write('a'); ows.close(); // close方法会自动触发缓冲区的刷新,也可以单独调用ows.flush()再close
再细说下两个write方法的差异:
FileOutputStream.write(int b):不管你传的是字符还是整数,它只取参数的低8位(一个字节)直接写入,没有自己的用户态缓冲区,数据要么立刻写,要么由操作系统的磁盘缓存处理,程序结束时会自动刷入磁盘。OutputStreamWriter.write(int c):它接收的是一个字符的Unicode码点(int类型),会先把这个字符按照指定编码(默认是系统编码)转换成字节,然后存入内部缓冲区。只有当缓冲区被填满、手动调用flush(),或者调用close()关闭流的时候,才会把缓冲区里的字节交给底层的FileOutputStream写入磁盘。
所以总结一下:不是OutputStreamWriter的write方法不行,是你没做刷新/关闭流的收尾操作!而字节流因为没有用户态的缓冲区,或者说程序结束时系统帮你兜底了,所以能看到写入结果。
内容的提问来源于stack exchange,提问作者jzian
相关产品推荐
相关产品推荐

