请选择 进入手机版 | 继续访问电脑版

[IO] JavaIO之FileInputStream 与 FileOutputStream(九)

编程语言 编程语言 1413 人阅读 | 0 人回复

从名字应该可以看得出来:

从一个文件中读取数据,或者将数据写入到一个文件中

FileInputStream

image.png

image.png

nio的东西,暂时不说了

构造方法

FileInputStream既然是从文件读取数据 那么构造方法的首要作用也就是要唯一确定一个文件 根据之前的文章,要么使用File描述,要么可以使用String的路径名,再或者使用文件描述符可以定位文件 所以,FileInputStream的构造方法也就这三种形式

image.png

通过String的版本可以发现,实际上使用的还是File版本的方法

image.png

File版本的方法会设置fd 和 path的值

image.png

而文件描述符版本的却不会设置path

image.png

刚才也说了FileInputStream(String name) 是调用的File类型入参的构造方法 从上面的代码也看得出来,实际上干活的也就只是另外的两个方法 他们都有一个fd.attach(this) 关于这个点,可以查看文件描述符章节中说到的attach方法 是为了把所有的跟某个文件描述符相关的流都记录下来,毕竟一个文件可能被多个流打开

还需要注意的是 FileInputStream(FileDescriptor fdObj) 版本直接赋值参数到fd FileInputStream(File file) 每次都是new FileDescriptor();

read

read方法读取一个字节 带数组参数的read方法将数据读取到字节数组中,并且返回实际读取的个数 跟InputStream是一样的 看得出来,如同我们之前说过的那样,文件的读写操作依赖于操作系统

所以 所有的read都歇菜了,最终依赖的都是本地方法

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

image.png

skip(long n) available()

读的能力都没有,需要借助本地方法 自然是没有能力跳过和获取可用个数的,所以仍旧是依赖的本地方法

public native long skip(long n) throws IOException;
public native int available() throws IOException;

close

FileInputStream打开的可是实实在在的资源 所以close方法肯定是需要做些事情关闭资源的 注释中说的很清楚 关闭这个文件输入流并且释放所有与这个流相关的系统资源 如果这个流有关联的chanel ,那么也会关联这个channel 如下图所示源代码中 他是通过fd.closeAll() 方法来执行所谓的"释放所有相关资源"

image.png

看一个例子

image.png

image.png

在文件描述符一章节中,我们还记得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.png

image.png

FileOutputStream

FileOutputStream 用于写入诸如图像数据之类的原始字节的流 如果要写入字符流,请考虑使用 FileWriter

FileOutputStream的字段除了append以外,跟FileInputStream一样的, 含义作用 也是一样的

image.png

append 表示字节写入文件末尾处,而不是写入文件开始处,因为 文件输出字节流默认是数据写入文件开始部位

就像刚才说的那样,字段除了append以外,跟FileInputStream是一样的,含义也是一样的 进而,构造方法也是一样,只不过多了一个参数 append 这个boolean 类型的参数,正是用来设置append 标志是否是追加写

方法的内容都差不多的,不在详细介绍

image.png

write

write方法还是家族遗传的,本质不变 直接写入一个字节,或者从数组中写入字节到文件

//将指定字节写入此文件输出流
write(int);

//将 b.length 个字节从指定 byte 数组写入此文件输出流中
write(byte[] b);

//将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流
write(byte[] b,int off, int len);

和输入一样,借助于操作系统,,依赖于本地方法

image.png

etFD() getChannel() close() 和 FileInputStream中的一模一样 代码都是一样的

再一次的介绍了一对成员,你会发现越往后看越简单,因为他们的套路大多数是一样的 所以只需要自顶而下的了解清楚各个逻辑组成部分的含义功能 整个IO体系会越来越容易理解

common_log.png 转载务必注明出处:程序员潇然,疯狂的字节X,https://crazybytex.com/thread-145-1-1.html

关注下面的标签,发现更多相似文章

文章被以下专栏收录:

    黄小斜学Java

    疯狂的字节X

  • 目前专注于分享Java领域干货,公众号同步更新。原创以及收集整理,把最好的留下。
    包括但不限于JVM、计算机科学、算法、数据库、分布式、Spring全家桶、微服务、高并发、Docker容器、ELK、大数据等相关知识,一起进步,一起成长。
热门推荐
[CXX1300] CMake '3.18.1' was not
[md][CXX1300] CMake '3.18.1' was not found in SDK, PATH, or
[若依]微服务springcloud版新建增添加一个
[md]若依框架是一个比较出名的后台管理系统,有多个不同版本。
解决waiting for all target devices to co
[md]解决Launching app ,waiting for all target devices to co