Java基础之IO流
参考博文:
https://www.cnblogs.com/progor/p/9357676.html
前言:
什么是流?
- 流是个抽象的概念,是对输入输出设备的抽象,输入流可以看作一个输入通道,输出流可以看作一个输出通道。
- 输入流是相对程序而言的,外部传入数据给程序需要借助输入流。
- 输出流是相对程序而言的,程序把数据传输到外部需要借助输出流。
什么是字节流?
字节流--传输过程中,传输数据的最基本单位是字节的流。
什么是字符流?
字符流--传输过程中,传输数据的最基本单位是字符的流。
字符编码方式不同,有时候一个字符使用的字节数也不一样,比如ASCLL方式编码的字符,占一个字节;而UTF-8方式编码的字符,一个英文字符需要一个字节,一个中文需要三个字节。
字节数据是二进制形式的,要转成我们能识别的正常字符,需要选择正确的编码方式。我们生活中遇到的乱码问题就是字节数据没有选择正确的编码方式来显示成字符。
从本质上来讲,写数据(即输出)的时候,字节也好,字符也好,本质上都是没有标识符的,需要去指定编码方式。
但读数据的时候,如果我们需要去“看数据”,那么字节流的数据需要指定字符编码方式,这样我们才能看到我们能识别的字符;而字符流,因为已经选择好了字符编码方式,通常不需要再改了(除非定义的字符编码方式与数据原有的编码方式不一致!)
在传输方面上,由于计算机的传输本质都是字节,而一个字符由多个字节组成,转成字节之前先要去查表转成字节,所以传输时有时候会使用缓冲区。
一、IO流的分类
注:下表中带下划线的是抽象类,不能创建对象。粗体部分是节点流,其他就是常用的处理流。
| 流分类 | 使用分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
| 抽象基类 | InputStream |
OutputStream |
Reader | Writer | |
| 节点流 | 访问文件 | FileInputStream | FileOutStream | FileReader | FileWriter |
| 访问数值 | ByteArrayInputStream | ByteArrayOutStream | CharArrayReader | CharArrayWriter | |
| 访问管道 | PipedInputStream | PipedOutStream | PipedReader | PipedWriter | |
| 访问字符串 | StringReader | StringWriter | |||
| 处理流 | 缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
| 转换流 | InputStreamReader | OutputStreamWriter | |||
| 对象流 | ObjectInputStream | ObjectOutputStream | |||
| 抽象基类(过滤) | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | |
| 打印流 | PrintStream | PrintWriter | |||
| 推回输入流 | PushbackInputStream | PushbackReader | |||
| 特殊流 | DataInputStream | DataOutputStream |
继承关系如下:

二、字节流与字符流
字节流的类通常以stream结尾
字节输入流
常用的字节输入流主要有:
- InputStream
- FileInputStream
- BufferedInputStream 【BufferedInputStream不是InputStream的直接实现子类,是FilterInputStream的子类】
他们的区别与用途:
- InputStream是字节输入流的抽象基类 ,InputStream作为基类,给它的基类定义了几个通用的函数:
- read(byte[] b):从流中读取b的长度个字节的数据存储到b中,返回结果是读取的字节个数(当再次读时,如果返回-1说明到了结尾,没有了数据)
read(byte[] b, int off, int len):从流中从off的位置开始读取len个字节的数据存储到b中,返回结果是实际读取到的字节个数(当再次读时,如果返回-1说明到了结尾,没有了数据)- close():关闭流,释放资源。
- FileInputStream主要用来操作文件输入流,它除了可以使用基类定义的函数外,它还实现了基类的read()函数(无参的):
- read():从流中读取1个字节的数据,返回结果是一个int,(如果编码是以一个字节一个字符的,可以尝试转成char,用来查看数据)。
- BufferedInputStream带有缓冲的意思,普通的读是从硬盘里面读,而带有缓冲区之后,BufferedInputStream已经提前将数据封装到内存中,内存中操作数据要快,所以它的效率要要非缓冲的要高。它除了可以使用基类定义的函数外,它还实现了基类的read()函数(无参的):
- read():从流中读取1个字节的数据,返回结果是一个int,(如果编码是以一个字节一个字符的,可以尝试转成char,用来查看数据)。
使用:
- InputStream是字节输入流的抽象基类 ,InputStream作为基类,给它的基类定义了几个通用的函数:
InputStream是抽象基类,所以它不可以创建对象,但它可以用来“接口化编程”,因为大部分子类的函数基类都有定义,所以利用基类来调用函数。
FileInputStream是用来读文件数据的流,所以它需要一个文件对象用来实例化,这个文件可以是一个File对象,也可以是文件名路径字符串.【这里文件不存在会抛错】
public static void readFile() throws IOException { //创建一个字节流 FileInputStream fileInputStream = new FileInputStream( new File("E:\\U盘资料备份\\19-4-23\\晨讲--接口和抽象类\\接口和抽象类.txt")); byte[] bs = new byte[1024]; //从第几个字节开始读 int last = 0; while (fileInputStream.read(bs)!=-1) { System.out.println(last+new String(bs)+(last+1024)); last+=1024; } //释放资源 fileInputStream.close(); }
- BufferedInputStream是一种封装别的流以提高效率的流,所以它的初始化需要一个的InputStream流对象。
public static void readFile() throws IOException { //创建一个字节流 FileInputStream fileInputStream = new FileInputStream( new File("E:\\U盘资料备份\\19-4-23\\晨讲--接口和抽象类\\接口和抽象类.txt")); BufferedInputStream bfis = new BufferedInputStream(fileInputStream); byte[] bs = new byte[1024]; //从第几个字节开始读 int last = 0; while (bfis.read(bs)!=-1) { System.out.println(last+new String(bs)+(last+1024)); last+=1024; } //释放资源 fileInputStream.close(); }
字节输出流
常用的字节输出流主要有:
- OutputStream
- FileOutputStream
- BufferedOutputStream 【BufferedOutputStream不是OutputStream的直接实现子类,是FilterOutputStream的子类】
他们的区别与用途:
- OutputStream是字节输出流的基类, OutputStream作为基类,给它的基类定义了几个通用的函数:
- write(byte[] b):将b的长度个字节数据写到输出流中。
- write(byte[] b,int off,int len):从b的off位置开始,获取len个字节数据,写到输出流中。
- flush():刷新输出流,把数据马上写到输出流中。
- close():关闭流,释放系统资源。
- FileOutputStream是用于写文件的输出流,它除了可以使用基类定义的函数外,还实现了OutputStream的抽象函数write(int b):
- write(int b):将b转成一个字节数据,写到输出流中。
- BufferedOutputStream像上面那个BufferedInputStream一样,都可以提高效率。它除了可以使用基类定义的函数外,它还实现了OutputStream的抽象函数write(int b):
- write(int b):将b转成一个字节数据,写到输出流中。
使用:
- OutputStream是抽象基类,所以它不能实例化,但它可以用于接口化编程。
- FileOutputStream是用于写文件的输出流,所以它需要一个文件作为实例化参数,这个文件可以是File对象,也可以是文件路径字符串。【如果文件不存在,那么将自动创建。】【FileOutputStream实例化时可以给第二个参数,第二个参数是是否使用追加写入默认,为true时代表在原有文件内容后面追加写入数据,默认为false】
三、IO流应用举例

浙公网安备 33010602011771号