likes
comments
collection
share

从零开始学Java之IO流中有哪些复杂的API?

作者站长头像
站长
· 阅读数 25

前言

在上一篇文章中,壹哥给大家科普了IO流的基本概念,现在你对IO流应该有了基本的认知。但是接下来壹哥还不能给你讲IO的具体用法,我们要先对IO流的API有个基本的认知,因为IO流的类和方法太多了,我们不得不专门学习一下。

------------------------------前戏已做完,精彩即开始----------------------------

全文大约【3100】 字,不说废话,只讲可以让你学到技术、明白原理的纯干货!本文带有丰富的案例及配图视频,让你更好地理解和运用文中的技术概念,并可以给你带来具有足够启迪的思考......

配套开源项目资料

Github: github.com/SunLtd/Lear…

Gitee: 一一哥/从零开始学Java

一. IO流的API

1. API分类

Java中关于IO流的API,总的来说共有四大类,分别如下:

  • InputStream---字节输入流;
  • OutputStream---字节输出流;
  • Reader-----字符输入流;
  • Writer------字符输出流。

在Java中,所有输入流类都是 InputStream(字节输入流)和 Reader(字符输入流)的子类,其中InputStream类是字节输入流的抽象类,Reader是字符输入流的抽象类;所有的输出流类都是OutputStream(字节输出流)和 Writer(字符输出流)的子类,其中OutputStream类是字节输出流的抽象类,Writer是字符输出流的抽象类。

1.1 字节流的抽象基类

其中,字节流主要有两个类:InputStream和OutputStream,分别用于读取和写入字节数据。所有的字节输入流类都是InputStream的子类,所有的字节输出流类都是OutputStream的子类,这两个类都是抽象类,不能直接使用,需要使用其子类进行实例化。InputStream与OutputStream的关系如下图所示:

从零开始学Java之IO流中有哪些复杂的API?

InputStream和OutputStream的子类包括:

  • FileInputStream和FileOutputStream:用于文件的读写操作;
  • ByteArrayInputStream和ByteArrayOutputStream:用于在内存中读写二进制数据;
  • PipedInputStream和PipedOutputStream:用于线程间的数据传输;
  • FilterInputStream和FilterOutputStream:用于装饰其他流,增加流的功能。

1.2 字符流的抽象基类

Java提供了两个字符流的抽象类:Reader 和 Writer,所有的字符输入流类都是Reader的子类,所有的字符输出流类都是Writer的子类。它们是抽象类,不能直接使用,我们需要使用它们的子类来进行具体的操作。

Reader和Writer的本质其实也是一个能自动编解码的InputStream和OutputStream。Reader和Writer的数据源虽然是字节,但我们读入写出的数据都是char类型的字符,这是因为Reader和Writer的内部会把读入写出的byte解码编码转换成char。Reader与Writer类关系如下图所示:

从零开始学Java之IO流中有哪些复杂的API?

其中的Reader类用来读取字符流的抽象类,它提供了一些用来读取字符的方法,我们可以使用它的子类来进行文件读取、网络读取等操作。常用的Reader子类如下:

  • FileReader:用于读取文件字符流。
  • InputStreamReader:从字节流到字符流的桥梁,它可以将字节流转换为字符流。
  • CharArrayReader:可以从字符数组中读取字符流。
  • BufferedReader:可以从字符流中缓存读取数据,提高效率。

而Writer类是用来写入字符流的抽象类,它提供了一些写入字符的方法,我们可以使用它的子类来进行文件写入、网络写入等操作。常用的 Writer 子类:

  • FileWriter:用于写入文件字符流。
  • OutputStreamWriter:从字符流到字节流的桥梁,它可以将字符流转换为字节流。
  • CharArrayWriter:可以将字符流写入到字符数组中。
  • BufferedWriter:可以缓存写入字符流,提高效率。

1.3 小结

对字节流和字符流的关系,我们可以用下图概括展示:

从零开始学Java之IO流中有哪些复杂的API?

Java中凡是由这四个基类派生出来的子类名称,都会以其父类名称作为子类名称的后缀,如InputStream的子类FileInputStream,Reader的子类FileReader。

接下来壹哥再分别把这4个基类里的核心子类及其API方法介绍一下。

2. InputStream字节输入流

2.1 InputStream的常见子类

以下是InputStream的常见子类,包括节点流和处理流两种类型。

从零开始学Java之IO流中有哪些复杂的API?

2.2 InputStream的常用方法

以下是InputStream类中的常用API方法。

int available() 从下一次调用此输入流的方法返回可从该输入流读取(或跳过)的字节数,而不会阻塞。

void close() 关闭此输入流并释放与流相关联的任何系统资源。 

void mark(int readlimit) 标记此输入流中的当前位置。 

boolean markSupported() 测试此输入流是否支持 mark和 reset方法。 

abstract int read() 从输入流读取数据的下一个字节。 

int read(byte[] b) 从输入流中读取一些字节数,并将它们存储到缓冲器阵列 b。 

int read(byte[] b, int off, int len) 从输入流读取最多 len个字节的数据到字节数组。

byte[] readAllBytes() 从输入流读取所有剩余字节。 

int readNBytes(byte[] b, int off, int len) 将所请求的字节数从输入流读入给定的字节数组。 

void reset() 将此流重新定位到最后在此输入流上调用 mark方法时的位置。 

long skip(long n) 跳过并丢弃来自此输入流的 n字节的数据。 

long transferTo(OutputStream out) 从该输入流中读取所有字节,并按读取的顺序将字节写入给定的输出流。

3. OutputStream字节输出流

3.1 OutputStream的常见子类

以下是OutputStream的常见子类,包括节点流和处理流两种类型。

从零开始学Java之IO流中有哪些复杂的API?

3.2 OutputStream的常用方法

以下是OutputStream中的常用方法。

void close() 关闭此输出流并释放与此流相关联的任何系统资源。 

void flush() 刷新此输出流并强制任何缓冲的输出字节被写出。 

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

void write(byte[] b, int off, int len) 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。 

abstract void write(int b) 将指定的字节写入此输出流。 

4. Reader字符输入流

4.1 Reader的常见子类

以下是Reader的常见子类,包括节点流和处理流两种类型。

从零开始学Java之IO流中有哪些复杂的API?

4.2 Reader的常用方法

以下是Reader类中的常用方法。

abstract void close() 关闭流并释放与之相关联的任何系统资源。 

void mark(int readAheadLimit) 标记流中的当前位置。 

boolean markSupported() 告诉这个流是否支持mark()操作。 

int read() 读一个字符 

int read(char[] cbuf) 将字符读入数组。

abstract int read(char[] cbuf, int off, int len) 将字符读入数组的一部分。 

int read(CharBuffer target) 尝试将字符读入指定的字符缓冲区。

boolean ready() 告诉这个流是否准备好被读取。 

void reset() 重置流。 

long skip(long n) 跳过字符 

5. Writer字符输出流

5.1 Writer的常见子类

以下是Writer的常见子类,包括节点流和处理流两种类型。

从零开始学Java之IO流中有哪些复杂的API?

5.2 Writer的常见方法

以下是Writer类中的常用方法。

Writer append(char c) 将指定的字符附加到此writer

Writer append(CharSequence csq) 将指定的字符序列附加到此writer

Writer append(CharSequence csq, int start, int end) 将指定字符序列的子序列附加到此writer

abstract void close() 关闭流,先刷新

abstract void flush() 刷新流 

void write(char[] cbuf) 写入一个字符数组。 

abstract void write(char[] cbuf, int off, int len) 写入字符数组的一部分 

void write(int c) 写一个字符 

void write(String str) 写一个字符串 

void write(String str, int off, int len) 写一个字符串的一部分

6. IO流梳理总结

6.1 API完整类关系

最后,为了让大家对IO流有一个完整清晰地认知,针对以上这些java.io包中的API类关系,壹哥给大家绘制了下图:

从零开始学Java之IO流中有哪些复杂的API?

6.2 API归纳

从上图中,我们可以看到,Java中有各种各样的IO流API类,如果我们对这些API再细分一下,又可以归纳如下。

从零开始学Java之IO流中有哪些复杂的API?

文件操作流

  • FileInputStream:字节输入流;
  • FileOutputStream:字节输出流;
  • FileReader:字符输入流;
  • FileWriter:字符输出流

管道操作流

  • PipedInputStream:管道字节输入流;
  • PipedOutStream:管道字节输出流;
  • PipedReader:管道字符输入流;
  • PipedWriter:管道字符输出流

注意: PipedInputStream的实例要和PipedOutputStream的实例共同使用,共同完成管道的读取写入操作,主要用于线程操作。

字节/字符数组操作流

  • ByteArrayInputStream:字节数组输入流;
  • ByteArrayOutputStream:字节数组输出流;
  • CharArrayReader:字符数组输入流;
  • CharArrayWriter:字符数组输出流

Buffered缓冲流

  • BufferedInputStream:字节缓冲区输入流;
  • BufferedOutputStream:字节缓冲区输出流;
  • BufferedReader:字符缓冲区输入流;
  • BufferedWriter:字符缓冲区输出流

注意: 这是带缓冲区的处理流,缓冲流的底层从具体设备上获取数据,并将数据存储到缓冲区的数组内。通过缓冲区的read()方法从缓冲区获取具体的字符数据,这样就避免了每次都和硬盘打交道,提高了数据访问效率。

转化流

  • InputStreamReader:字符节点输入流
  • OutputStreamWriter:字符节点输出流

注意: 转换流,从字面意思可以看出它是字节流与字符流之间的桥梁,可以将字节转为字符,或者将字符转为字节。

数据流

  • DataInputStream:
  • DataOutputStream:

注意: 数据流可以解决我们输出数据类型的困难,数据流可以直接输出float类型或long类型,提高了数据读写的效率。

打印流

  • PrintStream
  • PrintWriter

注意: 一般是打印到控制台,可以进行控制打印的地方。

对象流

  • ObjectInputStream
  • ObjectOutputStream

注意: ObjectOutputStream可以将Java对象的原始数据类型写出到文件,实现对象的持久存储;ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

序列化流

  • SequenceInputStream

对于以上这些API类,大家先不用去记忆,只需要先有一个整体的印象即可。后面我们会在具体的案例中学习这些API,以后这些API用多了,自然就记住了。

------------------------------正片已结束,来根事后烟----------------------------

二. 结语

至此,壹哥就把IO流相关的API类及其方法告诉大家了,你能记住吗?今天的重点如下:

  • IO流有不同的分类标准,包括输入流和输出流、字节流和字符流、节点流和处理流;
  • 字节流主要有两个类:InputStream和OutputStream;
  • 字节流:二进制数据以byte为最小单位在InputStream/OutputStream中单向流动;
  • 字符流:字符数据以char为最小单位在Reader/Writer中单向流动;
  • Java提供了两个字符流的抽象类:Reader 和 Writer,所有的字符输入流类都是Reader的子类,所有的字符输出流类都是Writer的子类;
  • Reader和Writer的本质其实也是一个能自动编解码的InputStream和OutputStream。

在下一篇文章中,壹哥会带大家具体学习IO流API的使用,敬请继续关注哦。另外如果你独自学习觉得有很多困难,可以加入壹哥的学习互助群,大家一起交流学习。