IO 输入与输出(3) -- 节点流之一InputStream和OutputStream

节点流需要掌握以下知识:

  • 理解流的概念
  • InputStreamOutputStream
  • FileInputStreamFileOutputStream
  • ReaderWriter
  •  PipedInputStreamPipedOutputStream
  • ByteArrayInputStreamByteArrayOutputStream

 

流是字节序列的抽象概念,例如文件、输入输出设备、网络、内存等传输的数据序列都可以理解为流,流提供了一种由统一的方式从各种输入输出设备中读取和写入字节数据的方法。

 

这里一定要注意理解流和文件的差异:

 

   1.文件是数据的静态存储形式,而流是指数据传输时的形态。文件是一些具有永久存储及特定顺序的字节组成的一个有序的具有名称的一些数据的集合。而流提供了一种向IO设备写入字节和从IO设备中读取字节的方式。

      2.文件只是流可操作的IO设备之一,除了文件流,还有网络流,内存流,磁带流等等。

 

数据流是一串连续传输的数据的集合,就像水管里的水流一样,在水管的一端一点一点的供水,而在水管的另一端看到的是一股连续不断的水流,用于写入数据的程序可以一段接一段的向数据流管道中写入数据,这些数据段按先后顺序形成一个长的数据流,对于读取数据的程序来说,它看不到数据流在写入时的分段,它每次可以读取其中任意长度的数据,但只能先读取前面的数据后再读取后面的数据,不管数据是被分成多少次写入还是做为一个整体一次写入,读取的效果都应该是完全一样的。

 

java中提供了众多对流操作的类,通过这些流类应用程序可以方便的从各种IO设备中读取和向IO设备写入各种类型的数据。java的流分为两个大类:节点流类和过滤流类(也叫处理流类)。用于直接操作设备所对应的类叫节点类,节点流类所对应的IO源或者目标称为流节点,比如用一个类和某个文件或者网络直接相关联,那么这个类就叫做节点流类,那么这个文件或者这个网络就叫做流的节点。程序也可以通过一个间接的流类去调用节点流类,以达到更加灵活的读写各种类型的数据,比如要通过网络传输对象,我们就设计一种对象流的类,它可以把对象写入到网络当中去。那么这个类实际上是调用底层的网络流类。

 

首先我们先看一下InputStreamOutputStream

 

InputStream:程序可以从中连续读取字节的对象叫输入流,在java中用InputStream类来描述所有输入流的抽象概念。InputStream类是一个抽象类,它没有具体的对应到流设备,而是描述了所有流设备的共性。对应的网络,管道,内存,文件等具体IO设备的那些流类都是InputStream的子类,例如之后还会介绍到的FileInputStream类。

 

InputStream有以下方法:

    a)         int read(): 从输入流中读取一个字节的内容,并且把这个字节的内容以整数的方式返回。如果碰到这个流的结束,返回值就是-1,如果流没有结束而且暂时还没有数据可读,read()就会阻塞运行程序的执行过程,直到流中有新的数据可读。

 

    b)         int read(byte[] b): 用于从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中,最多读取的字节长度就是字节数组的长度,由于流中不一定有很多个数的字节可读,那么实际上它读取的个数以read()的返回值为准。

 

如果 b 的长度为 0,则不读取任何字节并返回 0;否则,尝试读取至少一个字节。如果因为流位于文件末尾而没有可用的字节,则返回值 -1;否则,至少读取一个字节并将其存储在 b 中。

 

将读取的第一个字节存储在元素 b[0] 中,下一个存储在 b[1] 中,依次类推。读取的字节数最多等于 b 的长度。设 k 为实际读取的字节数;这些字节将存储在 b[0] b[k-1] 的元素中,不影响 b[k] b[b.length-1] 的元素。

(以上内容摘自JDK文档)

 

    c)         read(byte[] b, int off, int len): 将输入流中最多 len 个数据字节读入 byte 数组中,从数组的下标off开始读入

 

    d)         long skip(long n): 跳过输入流中的n个字节,并返回实际跳过的字节数,一般用于包装类当中。

 

    e)         int available(): 返回当前输入流中可读的字节数,检测流中确实有数据可读的时候再去调用read(),这样就可以避免程序发生阻塞,如果程序要不停的实时的从流中读取数据,每次都要用available()来检查一下。这样就会消耗较多的CPU资源,还不如在一个单独的线程中直接循环的调用read(),当流中没有数据,read()就会阻塞,这样几乎不占用CPU资源。

 

    f)          void mark(int readlimit): 用于在输入流当中建立一个标记,它接受一个参数,意思是从这个标记的开始最多还能够读取多少个字节,它也是用于包装类的方法。

 

    g)         void reset(): 它和mark()方法配合使用,当在A这个地方做完标记以后,接着读取几个字节,到B以后再调用reset(),下次再读的话又从A的地方开始读取数据,就是让指针回到以前做的标记处。

 

    h)         boolean markSupported(): 返回当前的流对象是否支持mark()reset()操作。

 

    i)           void close(): 用于所有流操作以后关闭。

 

OutputStream:程序可以向其中连续写入字节的对象叫输出流,在java中用OutputStream类来描述所有输出流的抽象概念。它也是抽象类,也只是描述了输出时的一些共性。

OutputStream
有以下方法:

 

    a)         void write(int b): 将一个整数当中的最低一个字节(整数是4个字节)内容写到输出流中,最高字节部分被舍弃。

 

    b)         write(byte[] b): b.length 个字节从指定的 byte 数组写入输出流。

 

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

 

    d)         void flush(): 用于将内存缓冲区中的内容彻底的清空并且输出到IO设备当中。

 

    e)         void close(): 关闭输出流对象

 

版权声明: 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值