zoukankan      html  css  js  c++  java
  • [八]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()
    连读的能力都没有,需要借助本地方法
    自然是没有能力跳过和获取可用个数的
    所以仍旧是依赖的本地方法

    public native long skip(long n) throws IOException;

    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体系会越来越容易理解


  • 相关阅读:
    PAT 甲级 1129 Recommendation System
    PAT 甲级 1129 Recommendation System
    PAT 甲级 1128 N Queens Puzzle (20 分)
    PAT 甲级 1128 N Queens Puzzle (20 分)
    PAT 甲级 1096 Consecutive Factors (20 分)
    PAT 甲级 1096 Consecutive Factors (20 分)
    PAT 甲级 1135 Is It A Red-Black Tree (30 分)
    PAT 甲级 1135 Is It A Red-Black Tree (30 分)
    AcWing 900. 整数划分
    AcWing 899. 编辑距离 线性dp
  • 原文地址:https://www.cnblogs.com/noteless/p/9632570.html
Copyright © 2011-2022 走看看