[JDK1.8] Java-I/O流使用概述

概述

Java I/O分为两大类: 字节与数字型 I/O字符与文本型 I/O。而Java中提供的所有I/O操作类,都是基于流(Stream)的概念。

流(Stream)即非确定长度的有序字节序列。
无论是字节流还是字符流,二者都是基于字节数据,只不过数据的宽度不同。
Java中默认 字节流按照1byte(8bit)单位数据量读取,字符流按照2byte(16bit,即Java默认的内存字符存储格式 Unicode(UTF-16))。

按照上述两种概念,Java在具体实现当中,提供了如下两种方式:

  • 字节输入流(InputStream)与字节输出流(OutputStream)
  • 字符输入流(Reader)与字符输出流(Writer)

用户可以通过上述两种流操作,进行本地数据、网络数据的读写,也可以通过这些流操作达成程序间数据交互的目的。Java还在基本读写功能的基础上,提供了压缩、加密、数据过滤等功能类。

本文的重点在于介绍基础I/O读写操作类及相互之间的关系。

I/O流类介绍

Java 8中java.io包下所有的流关系图如下:

[JDK1.8] Java-I/O流使用概述_第1张图片

关于每个类的概要描述,可以参考 java.io包类摘要,或者到官网查询相关的文档资料,也可以下载相关的源码进行阅读。

节点流和处理流

Java当中按照流的处理位置,还可以分为节点流处理流

  • 节点流 可以从或向一个特定的地方(节点)读写数据。
  • 处理流 是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。

节点流类

节点流类在java.io中所占比例较少,主要用于最基本的数据处理:
abstract InputStream
- ByteArrayInputStream 字节数组输入流,区别于CharArrayReader
- FileInputStream 文件字节输入流,区别于FileReader
- PipedInputStream 管道字节输入流,区别于PipedReader
- StringBufferInputStrem 已过时,使用StringReader替代
abstract OutputStream
- ByteArrayOutputStream 字节数组输出流,区别于CharArrayWriter
- FileOutputStream 文件字节输出流,区别于FileWriter
- PipedOutputStream 管道字节输出流,区别于PipedWriter
abstract Reader
- CharArrayReader 字符数组输入流,区别于ByteArrayReader
- FileReader 文件字符输入流,区别于FileInputStream
abstract Writer
- CharArrayWriter 字符数组输出流,区别于ByteArrayWriter
- FileWriter 文件字符输出流,区别于FileOutputStream
- PipedWriter 管道字符输出流,区别于PipedOutputStream
- StringWriter 字符串输出流,不会抛出IOException

处理流类

从java.io包中类的角度讲,继承了 FilterInputStream, FilterOutputStream, FilterReader, FilterWriter的类均为是处理流

这四个类及其子类,如基类命名的Filter一样,是作为”过滤”的中间介质存在,可以对已存在的流进行过滤处理,包含加密、压缩、转译、缓冲等特殊操作。譬如使用BufferedInputStream过滤FileInputStream,即可拥有缓冲功能,从而提高文件读取性能。在java.io以外的包,譬如java.security中有关于信息加密解密的流,亦继承于FilterInputStream等过滤类。
值得注意的是,上述四个Filter类中,字符流的两个Filter基类(FilterReader/FilterWriter)均为抽象(abstract)方法,而字节流的是具体方法

继承Filter类的处理流类有:
FilterInputStream
- BufferedInputStream 缓冲字节输入流,System.in 即为该类的一个实例
- DataInputStream 数据字节输入流
- PushbackInputStream 推回字节输入流
- LineNumberInputStream 已过时,使用LineNumberReader替代
FilterOutputStream
- BufferedOutputStream 缓冲字节输出流
- DataOutputStream 数据字节输出流
- PrintStream(不会抛出IOException)打印字节流,System.errSystem.out是该类的实例
abstract FilterReader
- PushbackReader 推回字符输入流
abstract FilterWriter java.io包中无对应的子类实现

除Filter相关类外,其余的处理流类如下:
abstract InputStream
- ObjectInputStream 对象字节输入流,与ObjectOutputStream配套使用
- SequenceInputStream 序列字节输入流,用于串行多个InputStream处理
abstract OutputStream
- ObjectOutputStream 对象字节输出流,与ObjectInputStream配套使用
abstract Reader
- BufferedReader 缓冲字符输入流
- LineNumberReader 按行读取字符输入流,是BufferedReader的子类
- InputStreamReader 字节流-字符流桥接类
abstract Writer
- BufferedWriter 缓冲字符输出流
- LineNumberWriter 按行读取字符输出流,是BufferedWriter的子类
- OutputStreamWriter 字节流-字符流桥接类
- PrintWriter 打印字符输出流,类方法不会抛出I/O Exception

功能划分

从功能需求的角度,java.io中提供的若干个类,在不考虑字节流和字符流区分的情况下,一些基本或特殊功能的使用原则如下:

基本分类

处理文件(可根据文件类型进行选择)
- FileInputStream
- FileOutputStream
- FileReader
- FileWriter
按行处理文件(按行处理文本数据)
- LineNumberReader
处理字节数组byte[]
- ByteArrayInputStream
- ByteArrayOutputStream
处理字符数组char[]
- CharArrayReader
- CharArrayWriter
处理字符串
- StringReader
- StringWriter
处理网络数据流(网络数据包括)
- InputStream
- OutputStream
- Reader
- Writer
格式化输出(格式化输出字节或字符数据)
- PrintStream
- PrintWriter
使用缓冲功能(使用一块缓冲区域保存数据后一次写入以提高性能)
- BufferedInputStream
- BufferedOuputStream
- BufferedReader
- BufferedWriter
字节流转字符流(字节流数据向字符流数据的转换媒介)
- InputStreamReader
- OutputStreamWriter
进程间通信
- PipedInputStream 只能连接PipedOutputStream
- PipedOutputStream
- PipedReader 只能连接PipedWriter
- PipedWriter
推回输入流(多用于Parser场景,譬如编译器之类)
- PushbackInputStream
- PushbackReader
组合输入流(多个输入流的macro类)
- SequenceInputStream

补充说明

最后补充几个小笔记:

  • PrintStream在JDK1.1时被标注Deprecated,又在JDK1.2时移除该标注,仅因为System.out使用PrintStream实现,从而导致该类无法被抛弃。
  • OutputStream的flush方法会清空对应缓冲区。
  • FileInputStream的finalize方法在FileInputStream对象被GC时进行调用,以确保文件在垃圾回收前被关闭。不需要手动调用finalize方法,但是如果继承了该类,则必须在子类中调用super.finalize()方法。
  • 可以同时通过多个FileInputStream流处理同一文件,而输出流则不行(涉及同步等问题)。
  • PrintStream可用来将输出流重定向,譬如写入一个文本等等。
  • 虽然FilterInputStream和FilterOuputStream没有abstract修饰,但是其构造函数有protected修饰,故而只能通过子类创建对应对象。

本文舍弃了诸多类的方法、细节实现描述,假如一一叙述,篇幅则会过长,且并非本文目标。
如需了解详细内容,建议在使用的同时翻阅相应的源码、书籍,而不是一次性接收,否则,后续仍会遗忘其设计初衷。

参考链接

  • java IO选择流的原则及其与IO流相关类的关系
  • IO流输入输出流,字符字节流
  • 深入了解JDK1.8 从Package java.io开始
  • Java IO
  • JAVA的节点流和处理流
  • IO、文件、NIO

你可能感兴趣的:(D0004,Java)