天天看点

Java IO 之 FileInputStream & FileOutputStream源码分析一、引子二、FileInputStream源码分析三、FileOutputStream 源码分析四、使用案例五、思考与小结

文件,作为常见的数据源。关于操作文件的字节流就是 — fileinputstream & fileoutputstream。它们是basic io字节流中重要的实现类。

fileinputstream源码如下:

1. 三个核心方法

三个核心方法,也就是override(重写)了抽象类inputstream的read方法。

int read() 方法,即

代码实现中很简单,一个try中调用本地native的read0()方法,直接从文件输入流中读取一个字节。iotrace.filereadend(),字面意思是防止文件没有关闭读的通道,导致读文件失败,一直开着读的通道,会造成内存泄露。

int read(byte b[]) 方法,即

代码实现也是比较简单的,也是一个try中调用本地native的readbytes()方法,直接从文件输入流中读取最多b.length个字节到byte数组b中。

int read(byte b[], int off, int len) 方法,即

代码实现和 int read(byte b[])方法 一样,直接从文件输入流中读取最多len个字节到byte数组b中。

可是这里有个问答: q: 为什么 int read(byte b[]) 方法需要自己独立实现呢? 直接调用 int read(byte b[], int off, int len) 方法,即read(b , 0 , b.length),等价于read(b)? a:待完善,希望路过大神回答。。。。向下兼容?? finally??

2. 值得一提的native方法

上面核心方法中为什么实现简单,因为工作量都在native方法里面,即jvm里面实现了。native倒是不少一一列举吧:

native void open(string name) // 打开文件,为了下一步读取文件内容 native int read0() // 从文件输入流中读取一个字节 native int readbytes(byte b[], int off, int len) // 从文件输入流中读取,从off句柄开始的len个字节,并存储至b字节数组内。 native void close0() // 关闭该文件输入流及涉及的资源,比如说如果该文件输入流的filechannel对被获取后,需要对filechannel进行close。

其他还有值得一提的就是,在jdk1.4中,新增了nio包,优化了一些io处理的速度,所以在fileinputstream和fileoutputstream中新增了filechannel getchannel()的方法。即获取与该文件输入流相关的 java.nio.channels.filechannel对象。

fileoutputstream 源码如下:

三个核心方法,也就是override(重写)了抽象类outputstream的write方法。

void write(int b) 方法,即

代码实现中很简单,一个try中调用本地native的write()方法,直接将指定的字节b写入文件输出流。iotrace.filereadend()的意思和上面fileinputstream意思一致。

void write(byte b[]) 方法,即

代码实现也是比较简单的,也是一个try中调用本地native的writebytes()方法,直接将指定的字节数组写入该文件输入流。

void write(byte b[], int off, int len) 方法,即

代码实现和 void write(byte b[]) 方法 一样,直接将指定的字节数组写入该文件输入流。

native void write(int b, boolean append) // 直接将指定的字节b写入文件输出流 native native void writebytes(byte b[], int off, int len, boolean append) // 直接将指定的字节数组写入该文件输入流。

相似之处:

其实到这里,该想一想。两个源码实现很相似,而且native方法也很相似。其实不能说“相似”,应该以“对应”来概括它们。 它们是一组,是一根吸管的两个孔的关系:“一个input一个output”。 休息一下吧~ 看看小广告:

下面先看代码:

运行后,会发现根目录中出现了一个“data.txt”文件,内容为上面的代码。

1. 简单地分析下源码:

1、创建了fileinputstream,读取该代码文件为文件输入流。 2、创建了fileoutputstream,作为文件输出流,输出至data.txt文件。 3、针对流的字节数组,一个 read ,一个write,完成读取和写入。 4、关闭流

2. 代码调用的流程如图所示:

Java IO 之 FileInputStream & FileOutputStream源码分析一、引子二、FileInputStream源码分析三、FileOutputStream 源码分析四、使用案例五、思考与小结

3. 代码虽简单,但是有点小问题:

fileinputstream.available() 是返回流中的估计剩余字节数。所以一般不会用此方法。 一般做法,比如创建一个 byte数组,大小1k。然后read至其返回值不为-1,一直读取即可。边读边写。

fileinputstream & fileoutputstream 是一对来自 inputstream和outputstream的实现类。用于本地文件读写(二进制格式按顺序读写)。

本文小结:

1、fileinputstream 源码分析 2、fileoutputstream 资源分析 3、fileinputstream & fileoutputstream 使用案例 4、其源码调用过程 欢迎点击我的博客及github — 博客提供rss订阅哦!