[八]JavaIO之FileInputStream 与 FileOutputStream


接下来介绍 FileInputStream  和 FileOutputStream
如今看名字应该能够看得出来:
他就是从一个文件中读取数据
或者将数据写入到一个文件中

FileInputStream

既然是从文件读取数据,那么天然要记录文件自己的信息
因此有文件描述符 fd以及 path路径名
显然,文件描述符是对文件最直接的描述
若是是使用文件描述符做为参数的话,path的值将会是null
image_5b9859e0_27a4

image_5b9859e1_472f 

nio的东西,暂时不说了 数组


构造方法
FileInputStream既然是从文件读取数据
那么构造方法的首要做用也就是要惟一肯定一个文件
根据以前的文章,要么使用File描述,要么可使用String的路径名,再或者使用文件描述符能够定位文件
因此,FileInputStream的构造方法也就这三种形式
image_5b9859e1_4d32
经过String的版本能够发现,实际上使用的仍是File版本的方法
image_5b9859e1_3f2f
File版本的方法会设置fd 和 path的值
image_5b9859e1_75b

而文件描述符版本的却不会设置path
image_5b9859e1_30db
刚才也说了FileInputStream(String name) 是调用的File类型入参的构造方法
从上面的代码也看得出来,实际上干活的也就只是另外的两个方法
他们都有一个fd.attach(this)  关于这个点,能够查看文件描述符章节中说到的attach方法
是为了把全部的跟某个文件描述符相关的流都记录下来,毕竟一个文件可能被多个流打开
还须要注意的是
FileInputStream(FileDescriptor fdObj) 版本直接赋值参数到fd
FileInputStream(File file)  每次都是new FileDescriptor();




read方法
read方法读取一个字节
带数组参数的read方法将数据读取到字节数组中,而且返回实际读取的个数
跟InputStream是同样的
看得出来,如同咱们以前说过的那样,文件的读写操做依赖于操做系统,因此
全部的read都歇菜了,最终依赖的都是本地方法

还有一个须要时刻记住的是,read 阻塞选手
image_5b9859e1_5933


skip(long n)  available()
连读的能力都没有,须要借助本地方法
天然是没有能力跳过和获取可用个数的
因此仍旧是依赖的本地方法

this

public native long skip(long n) throws IOException; app

public native int available() throws IOException;

Close方法
FileInputStream打开的但是实实在在的资源
因此close方法确定是须要作些事情关闭资源的
注释中说的很清楚
关闭这个文件输入流而且释放全部与这个流相关的系统资源
若是这个流有关联的chanel ,那么也会关联这个channel
以下图所示源代码中
他是经过fd.closeAll()   方法来执行所谓的"释放全部相关资源"
image_5b9859e1_5cc7
看一个例子
image_5b9859e1_cf2
image_5b9859e1_3ae0
在文件描述符一章节中,咱们还记得fd.closeAll()  方法来执行所谓的"释放全部相关资源"
那不是释放了全部的么?
为何同一个File还能够打开多个流,关闭不受影响呢?

根本在于上面说到的构造方法中

FileInputStream(FileDescriptor fdObj) 版本直接赋值参数到fd
FileInputStream(File file)  每次都是new FileDescriptor();
他们对于使用File构造的,他们的fd每次都是新建的!!!!!
因此说不受影响的
closeAll 的是同一个fd的


getFD()   getChannel() 
getFD()   getChannel()  就是返回他们的值
若是fd不存在,抛出异常
从构造方法能够看得出来, 必然会有一个fd
getChannel nio的后续再说,没有就建立一个
 
image_5b9859e1_2df5
image_5b9859e1_7589



FileOutputStream

FileOutputStream 用于写入诸如图像数据之类的原始字节的流
若是要写入字符流,请考虑使用 FileWriter
FileOutputStream的字段除了append之外,跟FileInputStream同样的, 含义做用 也是同样的
image_5b9859e1_3605
append 表示字节写入文件末尾处,而不是写入文件开始处,由于 文件输出字节流默认是数据写入文件开始部位
就像刚才说的那样,字段除了append之外,跟FileInputStream是同样的,含义也是同样的
进而,构造方法也是同样,只不过多了一个参数  append
这个boolean 类型的参数,正是用来设置append 标志是不是追加写

方法的内容都差很少的,咱们不在详细介绍
image_5b9859e1_1da


write方法
write方法仍是家族遗传的,本质不变
直接写入一个字节,或者从数组中写入字节到文件
write(int) 将指定字节写入此文件输出流
write(byte[] b)  将 b.length 个字节从指定 byte 数组写入此文件输出流中
write(byte[] b,int off, int len)   将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流
和输入同样,借助于操做系统,,依赖于本地方法
image_5b9859e1_168f



getFD()   getChannel()   close()  和 FileInputStream中的如出一辙
代码都是同样的,再也不赘述


再一次的介绍了一对成员,你会发现越日后看越简单,由于他们的套路大多数是同样的
因此只须要自顶而下的了解清楚各个逻辑组成部分的含义功能
整个IO体系会愈来愈容易理解
相关文章
相关标签/搜索