1、什么是流
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
根据处理数据类型的不同分为:字符流和字节流;
根据数据流向不同分为:输入流和输出流。
输入流是相对程序而言的,外部传入数据给程序需要借助输入流。
输出流是相对程序而言的,程序把数据传输到外部需要借助输出流。
Java流操作有关的类或接口:
Java流类图结构:
2、字节流
字节流–传输过程中,传输数据的最基本单位是字节的流。
字节流的类通常以stream结尾。
2.1、字节输入流
常用的字节输入流主要有三个:InputStream
、FileInputStream
和BufferedInputStream
。
- InputStream:InputStream是字节输入流的抽象基类 ,InputStream作为基类,给它的基类定义了几个通用的函数:
方法声明 | 功能描述 |
---|---|
int read() | 从流中读取1个字节(8位)的数据,返回结果是一个int类型的整数 |
int read(byte[] b) | 从流中读取b的长度个字节的数据存储到b中,返回结果是读取的字节个数(当再次读时,如果返回-1说明到了结尾,没有了数据) |
int read(byte[] b, int off, int len) | 从流中读取1个字节(8位)的数据,返回结果是一个int类型的整数 |
void close() | 关闭流,释放资源 |
- FileInputStream:主要用来操作文件输入流,它除了可以使用基类定义的函数外,它还实现了基类的read()函数(无参的)
- BufferedInputStream:带有缓冲的意思,普通的读是从硬盘里面读,而带有缓冲区之后,BufferedInputStream已经提前将数据封装到内存中,内存中操作数据要快,所以它的效率要要非缓冲的要高。它除了可以使用基类定义的函数外,它还实现了基类的read()函数(无参的)。
2.2、字节输出流
常用的字节输出流主要有:OutputStream
、FileOutputStream
和BufferedOutputStream
。
- OutputStream:是字节输出流的基类, OutputStream作为基类,给它的基类定义了几个通用的函数:
方法声明 | 功能描述 |
---|---|
int write(int b) | 将b转成一个字节数据,写到输出流中 |
int write(byte[] b) | 将b的长度个字节数据写到输出流中 |
int write(byte[] b,int off,int len) | 从b的off位置开始,获取len个字节数据,写到输出流中 |
void flush() | 刷新输出流,把数据马上写到输出流中 |
void close() | 关闭流,释放资源 |
- FileOutputStream:是用于写文件的输出流,它除了可以使用基类定义的函数外,还实现了OutputStream的抽象函数write(int b)。
- BufferedOutputStream:像上面那个BufferedInputStream一样,都可以提高效率。它除了可以使用基类定义的函数外,它还实现了OutputStream的抽象函数write(int b)。
3、字符流
字符流的类通常以Reader和Writer结尾
3.1、字符输入流
常用的字节输出流主要有:Reader
、InputStreamReader
、FileReader
和BufferedReader
。
- Reader是字符输入流的抽象基类 ,它定义了以下几个函数:
方法声明 | 功能描述 |
---|---|
int read() | 读取单个字符,返回结果是一个int,需要转成char;到达流的末尾时,返回-1 |
int read(char[] cbuf) | 读取cbuf的长度个字符到cbuf这种,返回结果是读取的字符数,到达流的末尾时,返回-1 |
void close() | 关闭流,释放资源 |
- InputStreamReader: 可以把InputStream中的字节数据流根据字符编码方式转成字符数据流。它除了可以使用基类定义的函数,它自己还实现了以下函数:
read(char[] cbuf, int offset, int length) :从offset位置开始,读取length个字符到cbuf中,返回结果是实际读取的字符数,到达流的末尾时,返回-1。 - FileReader :可以把FileInputStream中的字节数据转成根据字符编码方式转成字符数据流。
- BufferedReader可以把字符输入流进行封装,将数据进行缓冲,提高读取效率。它除了可以使用基类定义的函数,它自己还实现了以下函数:
- read(char[] cbuf, int offset, int length) :从offset位置开始,读取length个字符到cbuf中,返回结果是实际读取的字符数,到达流的末尾时,返回-1;
- readLine() :读取一个文本行,以行结束符作为末尾,返回结果是读取的字符串。如果已到达流末尾,则返回 null。
3.2、字符输出流
常用的字节输出流主要有:Writer
、OutputStreamWriter
、FileWriter
和BufferedWriter
。
- Writer是字符输出流的抽象基类, ,它定义了以下几个函数:
方法声明 | 功能描述 |
---|---|
void write(char[] cbuf) | 往输出流写入一个字符数组 |
void write(int c) | 往输出流写入一个字符 |
void write(String str) | 往输出流写入一串字符串 |
void write(String str, int off, int len) | 往输出流写入字符串的一部分 |
void close() | 关闭流,释放资源 |
void flush() | 刷新输出流,把数据马上写到输出流中 |
- OutputStreamWriter可以使我们直接往流中写字符串数据,它里面会帮我们根据字符编码方式来把字符数据转成字节数据再写给输出流,它相当于一个中介\桥梁。
- FileWriter与OutputStreamWriter功能类似,我们可以直接往流中写字符串数据,FileWriter内部会根据字符编码方式来把字符数据转成字节数据再写给输出流。
- BufferedWriter比FileWriter还高级一点,它利用了缓冲区来提高写的效率。它还多出了一个函数:
newLine() :写入一个换行符。
4、字符流和字节流的区别
- 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
- 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。