一、前言
在变量、数组、对象、集合中存储的数据是暂时的,一旦程序结束就会丢失。为了能够永久保存程序中生成的数据,需要将数据保留到磁盘文件中。Java的IO流技术可以将数据保存到文本文件和二进制文件,以达到保存数据的目的。
对于平常的办公软件,像Excel、word和ppt文件,打开和编辑保存东西,都是需要利用IO流的。
二、IO流概念
- I: Input
- O: Output
- 流: 是一组有序的、有起点和终点的字节集合,是对数据传输的抽象。即:数据在设备之间的传输称为流。
注: java.io 包下提供了各种“流”类的接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据, 通过IO流可以实现文件的读、写。对于计算机来说,数据都是以二进制形式读取或者写入的。
三、IO流的分类
- 根据数据的流向分类: 输入流(读取文件到内存中)、输出流(将内存数据写入到硬盘文件中)
- 根据数据处理的不同类型分类: 字节流(按照byte读或写)、字符流(按照char读或写)
- 根据流的角色分类: 节点流(向一个节点读写数据)、处理流(封装现有的流,调用封装的功能实现数据的读写)、转换流
注: 一字符占2字节,一字节(byte)= 8位(bit),一个汉字占两个字节长度。
Java IO 流都是从 4 个抽象类基类中派生出来的 ,如下:
- InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流
- OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流
注意:
- 在java中只要"类名"以Stream结尾的都是字节流。以"Reader/Writer"结尾的都是字符流。
- 字节流一般用来处理图像,视频,以及PPT,Word类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等。字节流可以用来处理纯文本文件,但是字符流不能用于处理图像视频等非文本类型的文件。
四、文件(File)
4.1概念
文件是保存数据的地方,比如经常使用的word文档、txt文档、excel文件等,可以保存文字、图片、视频等。
4.2文件流
文件在程序中以流的方式来操作的。
如图:
五、输入流\输出流
4.1输入流
概念: 将数据从各种输入设备(包括文件、键盘等)中读取到内存中 。
流类封装在 java.io 包中,而且每个数据流都是一个对象 。
所有输入流类都是 InputStream 抽象类(字节输入流)和 Reader 抽象类(字符输入流)的子类 。
其中 InputStream 类是字节输入流的抽象类,是所有字节输入流的父类 ,
InputStream 类 是抽象类,不能被实例化 。
InputStream类 常用方法:
名称 | 作用 |
---|---|
int read() | 从输入流读入一个 8 字节的数据,将它转换成一个 0~ 255 的整数,返回一个整数,如果遇到输入流的结尾返回 -1 |
int read(byte[] b) | 从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,返回的字节数表示读取的字节数,如果遇到输入流的结尾返回 -1 |
int read(byte[] b,int off,int len) | 从输入流读取若干字节的数据保存到参数 b 指定的字节数组中,其中 off 是指在数组中开始保存数据位置的起始下标,len 是指读取字节的位数。返回的是实际读取的字节数,如果遇到输入流的结尾则返回 -1 |
void close() | 关闭数据流,当完成对数据流的操作之后需要关闭数据流 |
int available() | 返回可以从数据源读取的数据流的位数。 |
skip(long n) | 从输入流跳过参数 n 指定的字节数目 |
boolean markSupported() | 判断输入流是否可以重复读取,如果可以就返回 true |
void mark(int readLimit) | 如果输入流可以被重复读取,从流的当前位置开始设置标记,readLimit 指定可以设置标记的字节数 |
void reset() | 使输入流重新定位到刚才被标记的位置,这样可以重新读取标记过的数据 |
上述最后 3 个方法一般会结合在一起使用,首先使用 markSupported() 判断,如果可以重复读取,则使用 mark(int readLimit) 方法进行标记,标记完成之后可以使用 read() 方法读取标记范围内的字节数,最后使用 reset() 方法使输入流重新定位到标记的位置,继而完成重复读取操作。
Java 中的字符是 Unicode 编码,即双字节的,而 InputerStream 是用来处理单字节的,在处理字符文本时不是很方便。这时可以使用 Java 的文本输入流 Reader 类。
4.2输出流
在 Java 中所有输出流类都是 OutputStream 抽象类(字节输出流)和 Writer 抽象类(字符输出流)的子类。其中 OutputStream 类是字节输出流的抽象类,是所有字节输出流的父类,其层次结构如图 所示。
OutputStream 类 是抽象类,不能被实例化 。
OutputStream 类 常用方法:
名称 | 作用 |
---|---|
int write(b) | 将指定字节的数据写入到输出流 |
int write (byte[] b) | 将指定字节数组的内容写入输出流 |
int write (byte[] b,int off,int len) | 将指定字节数组从 off 位置开始的 len 字节的内容写入输出流 |
close() | 关闭数据流,当完成对数据流的操作之后需要关闭数据流 |
flush() | 刷新输出流,强行将缓冲区的内容写入输出流 |
六、java.io包下需要掌握的16个流
文件专属:
java.io.FileInputStream
java.io.FileOutputStream
java.io.FileReader
java.io.FileWriter
转换流:(将字节流转换成字符流)
java.io.InputStreamReader
java.io.OutputStreamWriter
缓冲流专属:
java.io.BufferedReader
java.io.BufferedWriter
java.io.BufferedInputStream
java.io.BufferedOutputStream
数据流专属:
java.io.DateInputStream
java.io.DateOutputStream
标准输出流:
java.io.printWriter
java.io.printStream
对象专属流:
java.io.ObjectInputStream
java.io.ObjectOutputStream