首页 理论教育 Java流分类:简明实用指南

Java流分类:简明实用指南

时间:2023-11-16 理论教育 版权反馈
【摘要】:Java 流分为两种流:字节流:可以用于读写二进制文件及任何类型文件byte。在IO 包中,字节流的输入输出流分别用java.io.InputStream 和java.io.OutputStream 表示,字符流的输入输出流分别用java.io.Reader 和java.io.Writer 表示,具体分类如图8.1 所示。图8.2InputStream 与OutputStream 示意图在JDK 中,InputStream 和OutputStream 提供了一系列与读写数据相关的方法。表8-1InputStream 类的常用方法表8-2OutputStream 类写数据的方法表8-2 中列举了OutputStream 类的五个常用方法。图8.3InputStream 的子类体系结构图8.4OutputStream 的子类体系结构字节流读写文件。

Java流分类:简明实用指南

Java 流分为两种流:

(1)字节流:可以用于读写二进制文件及任何类型文件byte。

(2)字符流:可以用于读写文本文件,不能操作二进制文件。

IO 流有很多种,按照操作数据的不同,可以分为字节流和字符流,按照数据传输方向的不同又可分为输入流和输出流,程序从输入流中读取数据,向输出流中写入数据。在IO 包中,字节流的输入输出流分别用java.io.InputStream 和java.io.OutputStream 表示,字符流的输入输出流分别用java.io.Reader 和java.io.Writer 表示,具体分类如图8.1 所示。

图8.1 IO 流的分类

说明:

● InputStream 和OutputStream 是字节流,而Reader 和Writer 是字符流;

● InputStream 和Reader 是输入流,而OutputStream 和Writer 是输出流;

● 图中的4 个顶级类都是抽象类,并且是所有流类型的父类。

1. 字节流

在计算机中,无论是文本、图片、音频还是视频,所有文件都是以二进制(字节)形式存在的,I/O 流中针对字节的输入/输出提供了一系列的流,统称为字节流。字节流是程序中最常用的流。

在JDK 中,提供了两个抽象类InputStream 和OutputStream,它们是字节流的顶级父类,所有的字节输入流都继承自InputStream,所有的字节输出流都继承自OutputStream。为了方便理解,可以把InputStream 和OutputStream 比作两根“水管”,如图8.2 所示。

图8.2 InputStream 与OutputStream 示意图

在JDK 中,InputStream 和OutputStream 提供了一系列与读写数据相关的方法。下面先来了解一下InputStream 的常用方法,如表8-1 所示。

表8-1 中列举了InputStream 的四个常用方法。前三个read()方法都是用来读数据的,其中,第一个read()方法是从输入流中逐个读入字节,而第二个和第三个read()方法则将若干字节以字节数组的形式一次性读入,从而提高读数据的效率。在进行IO 流操作时,当前IO 流会占用一定的内存。由于系统资源宝贵,因此在IO 操作结束后,应该调用close()方法关闭流,从而释放当前IO 流所占的系统资源。

与InputStream 对应的是OutputStream。OutputStream 是用于写数据的,因此OutputStream提供了一些与写数据有关的方法,如表8-2 所示。

表8-1 InputStream 类的常用方法

表8-2 OutputStream 类写数据的方法

表8-2 中列举了OutputStream 类的五个常用方法。前三个是重载的write()方法,都是用于向输出流写入字节。其中,第一个方法逐个写入字节,后两个方法是将若干个字节以字节数组的形式一次性写入,从而提高写数据的效率。flush()方法用来将当前输出流缓冲区(通常是字节数组)中的数据强制写入目标设备,此过程称为刷新。close()方法是用来关闭流并释放与当前IO 流相关的系统资源。

InputStream 和OutputStream 这两个类虽然提供了一系列和读写数据有关的方法,但是这两个类是抽象类,不能被实例化。因此,针对不同的功能,InputStream 和OutputStream 提供了不同的子类,这些子类形成了一个体系结构,如图8.3 和图8.4 所示。

图8.3 InputStream 的子类体系结构

图8.4 OutputStream 的子类体系结构

(1)字节流读写文件。

由于计算机中的数据基本都保存在硬盘的文件中,因此,操作文件中的数据是一种很常见的操作。在操作文件时,最常见的就是从文件中读取数据并将数据写入文件,即文件的读写。针对文件的读写,JDK 专门提供了两个类,分别是FileInputStream 和FileOutputStream。

FileInputStream 是InputStream 的子类,它是操作文件的字节输入流,专门用于读取文件中的数据。由于从文件读取数据是重复的操作,因此需要通过循环语句来实现数据的持续读取。

(2)常用IO 流—— 文件对象。

目的:文件数据源File 类介绍(文件流对象中最为重要的File 类,对File 了解后对子类理解会更加容易)。

【例8.1】下面通过一个案例来实现字节流对文件数据的读取,如文件8-1 所示。

文件8-1 Example01.java

执行结果

FileOutputStream 是OutputStream 的子类,它是操作文件的字节输出流,专门用于把数据写入文件。

【例8.2】下面通过一个案例来演示如何将数据写入文件,如文件8-2 所示。

文件8-2 Example02.java

执行结果

高校大学生

【例8.3】下面通过一个案例来演示如何将数据追加到文件末尾,如文件8-3 所示。

文件8-3 Example03.java

执行结果

高校大学生欢迎你!

由于IO 流在进行数据读写操作时会出现异常,为了代码的简洁,在上面的程序中使用了throws 关键字将异常抛出。然而一旦遇到IO 异常,IO 流的close()方法将无法得到执行,流对象所占用的系统资源将得不到释放。因此,为了保证IO 流的close()方法必须执行,通常将关闭流的操作写在finally 代码块中,具体代码如下所示:

(3)文件的拷贝。(www.xing528.com)

在应用程序中,IO 流通常都是成对出现的,即输入流和输出流一起使用。例如文件的拷贝就需要通过输入流来读取文件中的数据,通过输出流将数据写入文件。

【例8.4】下面通过一个案例来演示如何进行文件内容的拷贝,如文件8-4 所示。

文件8-4 Example04.java

执行结果

拷贝文件所消耗的时间是:35156 毫秒

(4)字节流的缓冲区。

一个字节一个字节地读写,需要频繁的操作文件,效率非常低。这就好比从北京运送烤鸭上海,如果有一万只烤鸭,每次运送一只,就必须运输一万次,这样的效率显然非常低。为了减少运输次数,可以先把一批烤鸭装在车厢中,这样就可以成批地运送烤鸭,这时的车厢就相当于一个临时缓冲区。当通过流的方式拷贝文件时,为了提高效率也可以定义一个字节数组作为缓冲区。在拷贝文件时,一次性读取多个字节的数据,并保存在字节数组中,然后将字节数组中的数据一次性写入文件。

【例8.5】下面通过修改文件8-4 来学习如何使用缓冲区拷贝文件,如文件8-5 所示。

文件8-5 Example05.java

执行结果

拷贝文件所消耗的时间是:43 毫秒

在IO 包中提供两个带缓冲的字节流,分别是BufferedInputStream和BufferedOutputStream,它们的构造方法中分别接收InputStream 和OutputStream 类型的参数作为对象,在读写数据时提供缓冲功能。应用程序、缓冲流和底层字节流之间的关系如图8.5 所示。

图8.5 应用程序、缓冲流和底层字节流之间的关系

【例8.6】下面通过一个案例来学习BufferedInputStream 和BufferedOutputStream 这两个流的用法,如文件8-6 所示。

文件8-6 Example06.java

执行结果将会使des.txt 文件中的内容与src.txt 文件中的内容相同:

2. 字符流

在程序开发中,经常需要对文本文件的内容进行读取,如果想从文件中直接读取字符便可以使用字符输入流FileReader,通过此流可以从关联的文件中读取一个或一组字符。接下来通过一个案例来学习如何使用FileReader 读取文件中的字符和FileWriter 将字符写入文件中。

【例8.7】下面通过一个案例来学习如何使用FileReader 读取文件和FileWriter 写入文件以及两个输入输出流实现文件的拷贝,如文件8-7 所示。

文件8-7 Example07.java

执行结果

重庆城市管理职业学院网址:www.cswu.cn

【例8.8】使用FileWriter 将字符写入文件,如文件8-8 所示。

文件8-8 Example08.java

执行结果

你好,全国高校大学生!

使用字符流逐个字符的读写文件也需要频繁地操作文件,效率仍非常低。为此,同字节流操作文件一样,也可以使用提供的字符流缓冲区(类似于字节流缓冲区)和字符缓冲流(类似于字节缓冲流)进行读写操作,来提高执行效率。字符流缓冲区需要定义一个字符数组作为字符缓冲区,通过操作字符缓冲区来提高文件读写效率。字符缓冲流需要使用BufferedReader 和 BufferedWriter,其中 BufferedReader 用于对字符输入流进行操作,BufferedWriter 用于对字符输出流进行操作。在BufferedReader 中有一个readLine()方法,用于一次读取一行文本。

使用BufferedReader 和BufferedWriter 又是如何对文本内容进行读取,我们通过文件8-9来调试验证。

【例8.9】使用BufferedReader 和BufferedWriter,如文件8-9 所示。

文件8-9 Example09.java

执行结果会使des.txt 文件中的内容与src.txt 文件中的内容相同:

3. 转换流

前面提到IO 流可分为字节流和字符流,有时字节流和字符流之间也需要进行转换。在JDK中提供了两个类可以将字节流转换为字符流,它们分别是 InputStreamReader 和OutputStreamWriter。

OutputStreamWriter 是Writer 的子类,它可以将一个字节输出流转换成字符输出流,方便直接写入字符。而InputStreamReader 是Reader 的子类,它可以将一个字节输入流转换成字符输入流,方便直接读取字符。通过转换流进行数据读写的过程如图7.6 所示。

图8.6 通过转换流进行数据读写和过程

【例8.10】下面通过一个案例来学习如何将字节流转为字符流。为了提高读写效率,可以通过BufferedReader 和BufferedWriter 来实现转换工作,如文件8-10 所示。

文件8-10 Example10.java

执行结果

www.cswu.cn

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈