Java中流的概念
本文介绍了Java中流的概念,在Java中,程序所完成的输入输出是以流(Stream)的形式来实现的,流是一组有序的数据序列。按照数据的传输方向,流可分为输入流和输出流。从数据处理的单位划分,流可分为字节流和字符流。
目录
程序在运行过程中通常需要与外部设备进行交互,从外部设备读取数据或向外部设备发送数据,这就是输入输出。在这里,外部设备是指键盘、鼠标、控制台、显示器、打印机、文件和网络等,而程序可以看作是CPU和内存的组合。在Java中,程序所完成的输入输出是以流(Stream)的形式来实现的,流是一组有序的数据序列。流可以看作是建立在数据源和目的地之间的一条通信路径,数据在该路径上进行传输。
1. 流的分类
按照数据的传输方向,流可分为输入流和输出流。流的方向确定是相对程序而言的,向程序传递数据的流称为输入流,从程序发出数据的流称为输出流,如图1所示。对于输入数据流,只能从中读取数据而不能向其写入数据;对于输出数据流,只能向其写入数据而不能从中读取数据。
图1. 输入输出流
从数据处理的单位划分,流可分为字节流和字符流,以8位的字节为基本处理单位的流称为字节流,以16位的字符为基本处理单位的流称为字符流。字节是计算机进行数据处理的最小单位,因此,面向字节的流实际上可以处理任何格式的数据,这是因为具体的格式可以由程序自己负责解析。面向字符的流将输入、输出的数据解析为基于Unicode编码的字符,因此,其主要用于文本的处理。
2. 流的类层次
为了方便流的处理,Java中的流类都封装在java.io包中。在java.io包中有四个顶级抽象类:InputStream、OutputStream、Reader、Writer,其中,InputStream是字节输入流的根类, OutputStream是字节输出流的根类,Reader是字符输入流的根类, Writer是字符流输出流的根类,其它流类都是从这四个类继承而来的。定义在java.io包中流类的层次结构如图2所示。
图2. 流的类层次
由于InputStream、OutputStream、Reader和Writer是抽象类,而抽象类是不能进行实例化的,因此,在实际应用时使用的都是由它们所派生的子类,不同的子类应用于不同情况的数据输入输出操作。
3. 字节输入流
字节输入流的作用是从外部设备获取字节数据输入到相应的程序中。字节输入流的根类是InputStream,它是一个抽象类,其它所有的字节输入流类都从该类继承而来的。InputStream类定义了所有字节输入流类所共同具有的方法,其包含的主要方法如下:
- int read():从输入流中读取一个字节的二进制数据,然后以此数据为低位字节,配上一个全零字节,形成一个0-255之间的整数返回,如果到达流的末尾,则返回整数-1。
- int read(byte[] b):从输入流中读取最多b.length个字节的数据存储到字节数组b中,并返回实际成功读取的字节数。如果未到达流的末尾,则返回整数-1。
- int read(byte[] b, int off, int len):从输入流中读取len个字节的数据,将其存储到从下标off开始的字节数组b中,并返回实际读取的字节数。如果达到流的末尾,则返回整数-1。
- int available():该方法返回目前可以从输入流中读取的字节数。
- long ship(long l):逃过输入流中l个字节不读,返回实际跳过的字节数。
- boolean markSupported():用于指示输入流是否支持mark和reset操作,如果支持,则返回true,否则,返回fasle。
- void mark(int markarea):在输入流的当前位置放置一个标记,该流在读取markarea个字节前都保持有效。
- void reset(): 将输入流的指针重新定位到最后调用mark方法时的位置。
- void close():关闭输入流,释放与该输入流相关的资源。
常用的字节输入流类主要有文件输入流类(FileInputStream)、管道输入流类(PipedInputStream)、过滤器输入流类(FilterInputStream)、数据输入流类(DataInputStream)、缓冲区输入流类(BufferedInputStream)、回压输入流类(PushbackInputStream)、顺序输入流类(SequenceInputStream),字节数组输入流类(ByteArryInputStream)和对象输入流类(ObjectInputStream),这些类说明如表1所示。
表1 字节输入流类
类 | 含义 |
FileInputStream | 文件输入流,用于从文件读取数据 |
PipedInputStream | 管道输入流,用于从线程中读取数据 |
FilterInputStream | 过滤器输入流,它是一个装饰流,用于扩展其它字节输入流 |
DataInputStream | 数据输入流,其可以从字节输入流中读取基本类型的数据 |
BufferedInputStream | 缓冲区输入流,它在字节输入流的基础上增加一个输入缓冲区 |
PushbackInputStream | 回压输入流,其允许将读取的数据放回到输入流中以便于再次读取 |
SequenceInputStream | 顺序输入流,它可以将多个字节输入流合并成单一的字节输入流 |
ByteArryInputStream | 字节数组输入流,用于从字节数组中读取数据 |
ObjectInputStream | 对象输入流,它从输字节入流中读取对象并将其反序列化为Java对象 |
4. 字节输出流
字节输出流的作用是将字节数据从程序传输到相应的外部设备,例如,控制台、文件和网络等。字节输出流类的根类是OutputStream,它是一个抽象类,其它所有字节输入流类都是从该类继承而来的。OutputStream类定义了所有字节输出流类所共同具有的方法,其包含的主要方法如下:
- void write(int i):将i写入到输出流中,i是int型数据,长度为32位,写入i的低8位数据,24个高位字节被忽略。
- void write(byte b[]):将字节数组b中的全部数据写入到输出流。
- void write(byte b[], int off, int len):将字节数组b中从off开始的len个字节写入输出流中。
- void flush():将缓冲区中不够一个批次的数据强制提交。
- void close():关闭输出流,释放与该输出流相关的资源。
常用的字节输出流类主要有文件输出流类(FileOutputStream)、管道输出流(PipedOutputStream)、过滤器输出流类(FilterOutputStream)、数据输出流类(DataOutputStream)、缓冲区输出类(BufferedOutputStream)、打印输出流类(PrintStream)、字节输出流类(ByteArryOutputStream)和对象输出流类(ObjectOutputStream),这些类的说明如表2所示。
表2 字节输出流类
类 | 含义 |
FileOutputStream | 文件输出流,用于向文件写数据 |
PipedOutputStream | 管道输出流,用于向线程写数据 |
FilterOutputStream | 过滤器输出流,它是一个装饰流,用于扩展其它字节输出流 |
DataOutputStream | 数据输出流,可以向字节输出流中写入基本类型的数据 |
BufferedOutputStream | 缓冲区输出流,在字节输出流的基础上增加一个输出缓冲区 |
PrintStream | 打印输出流,用于向输出目标写入各种类型的数据 |
ByteArryOutputStream | 字节数组输出流,它可以将数据写入到字节数组中 |
ObjectOutputStream | 对象输出流,它可以将Java对象序列化为字节流 |
5. 字符输入流
字符输入流的作用是从外部设备获取字符数据输入到相应的程序中。Reader是字符输入流的根类,它是一个抽象类,其它所有字符输入类都从Reader类继承而来的。Reader类包含的主要方法如下:
- int read():从输入流中读取一个字符,如果达到流的末尾,则返回整数-1。
- int read(char[] cbuf):从输入流中读取多个字符的数据存储在数组cbuf中,并返回实际成功读取的字符数,如果到达流的末尾,则返回整数-1。
- int read(char[] cbuf, int off, int len):从输入流中读取最多len个字符的数据,将其存储到从下标off开始的字符数组b中,并返回实际读取的字符数,如果达到流的末尾,则返回整数-1。
- long skip(long n):从输入流中向后最多跳n个字符,并返回实际跳过的字节数。
- boolean ready():判断流是否做好读的准备。
- boolean markSupported():测试输入流是否支持mark和reset操作。
- void mark(int readAheadLimit):在输入流的当前位置放置一个标记,该流在读取readAheadLimit个字符前都保持有效。
- void reset():将输入流的指针重新定位到最后调用mark方法时的位置。
- void close():关闭输入流。
常用的字符输入流类主要有字符输入流类(InputStreamReader)、文件输入流类(FileReader)、字节数组输入流(CharArrayReader)、过滤器输入流类(FilterReader)、回压输入流类(PushbackReader)、缓冲区输入流类(BufferedReader)、行号输入流类(LineNumberReader)、管道输入流类(PipedReader)和字符串输入流类(StringReader),这些类的说明如表3所示。
表3 字符输入流类
类 | 含义 |
InputStreamReader | 字符输入流,它可以把字节输入流转换为字符输入流 |
FileReader | 文件输入流,用于从文件中读取字符数据 |
CharArrayReader | 字节数组输入流,用于从字符数组中读取数据 |
FilterReader | 过滤器输入流,它是一个装饰流,用于扩展其它字符输入流 |
PushbackReader | 回压输入流,它允许将读取的数据放回到输入流中以便于再次读取 |
BufferedReader | 缓冲区输入流,它在字符输入流的基础上增加一个输入缓冲区 |
LineNumberReader | 行号输入流,它在缓冲区输入流的基础上增加了行号 |
PipedReader | 管道输入流,用于从线程读取字符数据 |
StringReader | 字符串输入流,用于从字符串中读取字符 |
6. 字符输出流
字符输出流的作用是将字符数据从程序传输到相应的外部设备。Writer是字符输入流的根类,它是一个抽象类,其它所有字符输入类都从Writer类继承而来的。Writer类包含的主要方法如下:
- void write(int c):将字符c写入到输出流中。
- void write(char[] cbuf):将字符数组cbuf中的全部数据写入到输出流中。
- void write(char[] cbuf, int off, int len):将字符数组cbuf中从off开始的长为len个字符写入输出流中。
- void write(String str):将字符串str写入输出流中。
- long write(String str, int off, int len):将字符串str中从off开始i长度为len个字符写入到输出流中。
- void flush():将缓冲区中的数据写入到输出流中。
- void close():关闭输出流。
常用的字符输入流类主要有字符输出流类有字符输出流(OutputStreamWriter)、文件输出流(FileWriter)、字节数组输出流(CharArrayWriter)、过滤器输出流(FilterWriter)、缓冲区输出(BufferedWriter)、格式化输出流(PrintReader)和字符串输出流(StringWriter),这些类的说明如表4所示。
表4 字符输出流类
类 | 含义 |
OutputStreamWriter | 字符输出流,它可以字节输出流转换为字符输出流 |
FileWriter | 文件输出流,用于向文件写入字符数据 |
CharArrayWriter | 字节数组输出流,用于向字符数组中写入数据 |
FilterWriter | 过滤器输出流,它是一个装饰流,用于扩展其它字符输出流 |
BufferedWriter | 缓冲区输出流,它在字符输出流的基础上增加一个输出缓冲区 |
PrintReader | 打印输出流,用于向输出目标写入各种类型的文本数据 |
StringWriter | 字符串输出流,用于将字符写入字符串 |
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)