Java IO 流总结

Java IO 流的总结

Java IO 总结图

IO流

我们可以看到 IO流 分为字符流和字节流

字节流:表示字节输入输出流

字符流:表示字符输入输出流

Java中的字节流处理的最基本单位为单个字节,它通常用来处理二进制数据。

Java中的字符流处理的最基本的单元是Unicode码元,它通常用来处理文本数据。


下面具体说一下字符流与字节流

字节流

字节流的基类分别是 输入流: InputStream 和输出流: OutputStream

继承自InputStream派生的类都含有名为read的方法,用于读取单个字节或字节数组。

继承自OuputStream派生的类都含有名为write的方法,用于写入单个字节或字节数组。

InputStream

1, InputStream的作用

InputStream 的作用是用来表示那些从不同数据源产生输入的类,而最终结果就是通过read方法获得数据源的内容,从数据源中读出的内容用int或byte[]来表示.

2, InputStream的重要方法

InputStream中的方法


  1. read() : 返回输入流的下一个字节(next byte),如果已经到达输入流的末尾,那么返回-1
  2. read(byte b[]) 读取b.length长度的字节,存入到b中,如果已经到达末尾返回-1,否则返回成功写入到b中的字节数。
  3. read(byte b[], int off, int len) 取下len长度的字节,如果len为0,那么返回0,否则返回实际读入的字节数,读入的第一个字节存放在数据b[off]中,如果没有可读的,那么返回-1。
  4. skip(long n) 跳过,并丢弃掉n个字节,其最大值为2048。

PS: 四个方法中比较常用的 是 read(byte b[], int off, int len) 方法.
3, InputStream的具体实现类总结分析(比较常用到的)

1, ByteArrayInputStream(内存输入流)

它接收byte[]作为构造函数的参数,我们调用read方法时,就是从byte[]数组里,读取字节。

它共有两个构造函数(主要接受 byte数组来进行读取)

ByteArrayInputStream构造函数

2, FileInputStream(文件输入流)

支持提供文件名、File和FileDescription作为构造函数的参数,它的read调用的是底层的native方法。

jdk中有三个构造函数, android的sdk中该类有四个构造函数, 但是本质上都是一样的(主要用来包裹文件)
FileInput构造函数
第一个构造函数 String 类型的 FileName(文件路径) ,然后会把String抓换成一个File调用第二个构造函数

`public FileInputStream(String name) throws FileNotFoundException {
    this(name != null ? new File(name) : null);
}`

第三个构造函数 直接传入一个 FileDescriptor 对象,和第二个构造函数的区别问:
如果传入 File 则会 new 一个 FileDescriptor ,如果传入 FileDescriptor 则会直接使用这个 对象.

3, PipedInputStream(交换输入流)

通过通信管道来交换数据,如果两个线程希望进行数据的传输,那么它们一个创建管道输出流,另一个创建管道输入流,它必须要和一个PipedOutputStream相连接。

它共有四个构造函数

PipedInputStream构造函数

这四个构造函数可以分为两组,

`public PipedInputStream(PipedOutputStream src) throws IOException {
    this(src, DEFAULT_PIPE_SIZE);
}`

`public PipedInputStream() {
    initPipe(DEFAULT_PIPE_SIZE);
}`

这两组的区别是 如果传入一个 PipedOutputStream 会多一个和 PipedOutputStream 连接的方法来建立管道.

4, SequenceInputStream(合并输入流)

将多个InputStream连接在一起,一个读完后就完毕,并读下一个,它接收两个InputStream对象或者一个容纳InputStream对象的容器Enumeration。

它共有两个构造函数
SequenceInputStream构造函数

这两个构造函数很清晰, 一个接收两个流,一个接收多个流,它们最终会合并成一个流.

5, ObjectInputStream(对象输入流)

和一个InputStream相关联,源数据都是来自于这个InputStream ,主要用于对象进行反序列化, 即从一个序列化的文件中读取数据变成对象(主要用于序列化和反序列化)

它有两个构造函数, 其中一个 是 protected 修饰的, 就不说了,说一下 对外公布的 构造函数

`public ObjectInputStream(InputStream in) throws IOException {
    verifySubclass();
    bin = new BlockDataInputStream(in);
    handles = new HandleTable(10);
    vlist = new ValidationList();
    enableOverride = false;
    readStreamHeader();
    bin.setBlockDataMode(true);
}`

很明显这个构造函数是用来包裹一个 InputStream 主要用来进行反序列化的.

5, FilterInputStream

`protected FilterInputStream(InputStream in) {
    this.in = in;
}`

共1个构造函数 , 并且是 protected的类型, 不能创建对象

这个类很特殊,前面的InputStream子类都是传入一个数据源(Pipe/byte[]/File)等等,然后通过重写read方法从数据源中读取数据,而FilterInputStream则是将InputStream组合在内部,它调用in去执行InputStream定义的抽象方法,也就是说它不会改变组合在内部的InputStream所对应的数据源。

另外,它还新增了一些方法,这些方法底层还是调用了read方法,但是它封装了一些别的操作,比如DataInputStream中的readInt,它调用in连续读取了四次,然后拼成一个int型返回给调用者,之所以采用组合,而不是继承,目的是将(把二进制流转换成别的格式)和(从某个数据源中读出字节流)这两个操作独立开来,让它们可以随意地组合。

其下有三个类: BufferedInputStream(缓存流 , 常用) ; DataInputStream(不常用) ; PushbackInputStream(不常用)

  • BufferedInputStream
    有两个构造函数

BufferedInputStream构造函数

接受一个 InputStream , 来进行缓存从而进行有效率的读取和写入.

6, 其他
还有一个 LineNumberInputStream extends FilterInputStream 的LineNumberInputStream 数字流

和一个 StringBufferInputStream extends InputStream 的StringBufferInputStream 字符串缓存流

这两个流已经被弃用了,不需要考虑

InputStream 到这里就基本完毕了, 后面是 OutPutStream ,它和InputStream是对应的篇幅较少


OuputStream

OuputStream的作用

它决定了输出要去往的目标,和InputStream类似,也是一个抽象类,它的子类代表了输出所要去往的目标,我们主要关注的是write方法,前两个write方法最终都是调用了抽象的write(int oneByte)方法,最终怎么写入是由子类实现的。

OutputStream的具体实现类

1, ByteArrayOutputStream(两个构造函数)

在ByteArrayOutputStream的内部,有一个可变长的byte[]数组,当我们调用write方法时,就是向这个数组中写入数据,它还提供了toByteArray/toString方法,来获得当前内部byte[]数组中的内容。

2, FileOutputStream(五个构造函数, 主要增加一个boolean类型的值,用来标识 是否是在文件后面添加要输出的内容,如果为false , 则会把文件中的数据先清空在存入, 否则直接在文件的末尾进行添加写入)

它和 FileInputStream 类似,只不过写入的终点换成了所打开的文件。

3, PipedOutputStream(两个构造函数)

和PipedInputStream相关联。用于建立 通信管道来交换数据

4, ObjectOutputStream(两个构造函数, public 的只有一个构造函数, 传入一个OutPutStream)

和ObjectInputStream类似,只不过它内部组合的是一个OutputStream,当调用writeObject(Object object)方法时,其实是先将Object进行反序列化转换为byte,再输出到OuputStream所指向的目的地,主要用来对 object 进行序列化。

5, FilterOutputStream

它的思想和FilterInputStream类似,都是在内部组合了一个OuputStream,FilterOutputStream提供了写入int/long/short的write重载函数,当我们调用这些函数之后,FilterOutputStream最终会通过内部的OuputStream向它所指向的目的地写入字节。

其下有三个类: BufferedOutputStream(缓存流 , 常用) ; DataOutputStream(不常用) ; PrintStream(打印流 , 常用 ,10个构造函数, 主要用于包裹OutputStream和File)
- BufferedOutputStream,用来进行缓存进行更快速的 读取
- PrintStream,用来更加方便的输出

6, 注意

没有什么劳什子的 SequenceOutputStream(只能合并, 而不能拆分…话说怎么拆啊 ⊙﹏⊙)

OutputStream 到这里也基本完毕了, 后面是 字符输入输出流 ,内容不多


字符流: 主要用于文档的处理

Reader字符输入流

其实现类有

1, BufferReader

缓存流, 两个构造类, 主要用于包裹一个 Reader , 可以使用特定的方法 readLine() 直接一行一行的读取,这个类是 1.1加上去的, 也就是说 1.0的时候是没有这个 Reader的缓存字符流的

`public BufferedReader(Reader in) {
    this(in, defaultCharBufferSize);
}`

`public BufferedReader(Reader in, int sz) {
    super(in);
    if (sz <= 0)
        throw new IllegalArgumentException("Buffer size <= 0");
    this.in = in;
    cb = new char[sz];
    nextChar = nChars = 0;
}`
2, InputStreamReader

转换流, 四个构造函数, 主要用于 将流从 字节流转换为 字符流, 这个就是传说中的字节流和字符流连接的桥梁O__O “…
至于为什么, 因为 在Reader的所有实现类中只有它 可以接收一个 字节流 并处理, 所以它是 桥梁…

InputStreamReader构造函数

3, 其他实现类(个人感觉不常用)

1, StringReader

继承自Reader , 只有一个构造函数 ,public StringReader(String s) ,用于读取字符串, 功能叫少, 所以不常用

2, PipedReader

继承自Reader , 有四个构造函数 , 通信管道来交换数据 , 主要用来包裹PipedWriter 来创建一个通道 ,不常用

3, CharArrayReader

继承自Reader , 有两个构造函数 , 用于读取 字符列表

4, FilterReader

继承自Reader , 一个构造函数(还不对外公布) , 用于包裹一个Reader

` protected FilterReader(Reader in) {
    super(in);
    this.in = in;
}`

5, PushbackReader

继承自FilterReader , 两个构造函数 , 用于包裹一个Reader , 不常用

`public PushbackReader(Reader in) {
    this(in, 1);
}`

`public PushbackReader(Reader in, int size) {
    super(in);
    if (size <= 0) {
        throw new IllegalArgumentException("size <= 0");
    }
    this.buf = new char[size];
    this.pos = size;
}`

Writer字符输出流

其实现类有

1, BufferWriter

缓存流, 两个构造类, 用于包裹一个Writer,对应于 BufferReader

2, OutPutStreamWriter(桥梁..)

转换流, 四个构造函数 ,继承自Writer , 包裹OutputStream, 其他类似 InputStreamReader同时FileWriter继承自OutputStreamWriter , 一个构造函数 , 用于包裹 Writer

3, PrintWriter

打印流 , 9个构造函数 其中:

两个用于包裹Writer public PrintWriter(Writer out,boolean autoFlush);
两个用于包裹OutputStream , public PrintWriter(OutputStream out, boolean autoFlush);
五个用于包裹一个File 用来进行文件输出

4, 其他实现类(个人感觉不常用)

1, StringWriter

继承自Writer,两个构造函数

2, PipedWriter

继承自Writer , 两个构造函数

3, CharArrayWriter

继承自Writer , 两个构造函数

4, FilterWriter

继承自Writer ,两个构造函数


OVER

累了…..

继续努力

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值