分类图
参考: https://github.com/Snailclimb/Java-Guide
- 字节流和字符流
字节流:以字节为单位,每次次读入或读出是8位数据,可以读任何类型数据。所有带InputStream或OutputStream的io类
字符流:以字符为单位,每次次读入或读出是16位数据,其只能读取字符类型数据。所有带Reader或Writer的io类 - 输出流和输入流
输出流:只能进行写操作,比如output和writer。
输入流:只能进行读操作,比如input和read。 - 节点流和处理流
-
节点流:直接与数据源相连,读入或读出
- 文件流:FileReader、FileWriter、FileInputStream、FileOutputStream
- 线程管道通信流:PipedReader,PipedReader,PipedInputStream,PipedReader
- 数据类型流:StringWriter和StringReader、CharArrayReader和CharArrayWriter、ByteArrayInputStream和ByteArrayOutputStream
-
处理流:不能单独使用,要和节点流一起使用,在节点流外面套一层,用来修饰节点流和增加某种特性
- 缓存处理:BufferedReader和BufferWriter、BufferInputStream和BufferOutputStream
- 适配器:将字节流转换为字符流,有InputStreamReader、OutputStreamReader
- 数据类型处理:DataInputStream和DataOutputStream可以直接读取任何基础数据类型,ObjectInputStream和ObjectOutputStream用于对象序列化
- 合并流:SequenceInputStream可以认为是一个工具类,将两个或者多个输入流当成一个输入流依次读取
- 打印流:用来修饰输入输出流,可以打印任何的数据类型,有字节打印流PrintStream、字符打印流PrintWriter
IO基类
所有输入/输出流,字符/字节流的抽象基类,有InputStream/Reader,OutputStream/Writer过滤流基类
有FilterInputStream、FilterOutputStream、FilterReader FilterWriter。这些类都是抽象类,继承自InputStream、OutputStream、Reader、Writer ,本身没有实现任何功能,只是简单重写了父类的所有方法、要求子类(比如DataInputStream、DataOutputStream、BufferedInputStream、BufferedOutputStream、PrintStream等)必须重写核心方法、和提供具有自己特色的方法,为所有装饰类提供一个标准。推回输入流(PushbackInputStream和PushbackReader)
推回输入流,在使用read()读取数据时,可以使用unread()将指定的字节/数据推回输入流,下次读取时重新读取推回的字节/数据。
使用场景:
参考:http://xyiyy.iteye.com/blog/361351
读取同时存储有ASCII码英文字符(1个字节)与BIG5码中文字符(两个字节)的文本文件,使用推回输入流PushbackInputStream,每次读取2个字节,如果第1个字节是ASCII字符,则输出第1个字节,推回2个字节;如果不是则2个字节组成1个中文BIG5字符直接输出。
RandomAccessFile(随机流)
不属于IO流,支持对文件的读取和写入随机访问,是功能最丰富的文件内容访问类。
- 可以设置操作模式“rw”,支持同时读写(方便复制文件)
- 支持任何数据类型
- 通过改变文件指针位置,指定读写特定的文件位置
为什么需要 StringWriter和StringReader 这种类
并且值得注意的是StringWriter中,写入的数据只是存在于缓存中,并不会写入实质的存储介质之中。
刚开始我是比较奇怪这两个类为什么会存在的,因为这与直接使用String类来进行数据操作没什么区别,后来在网上看到别人的解释,如果你遇到一个情景是你必须使用一个Reader或者Writer来作为参数传递参数,但你的数据源又仅仅是一个String类型数据,无需从文件中写出,那么此时就可以用到它们。
PrintWriter和BufferedWriter的区别
从用途上,两者是完全可以替代的。
从使用上看,尽量用PrintWriter取代BufferedWriter。
下面是PrintWriter的优点:
- PrintWriter的print、println方法可以接受任意类型的参数(包括字节),而BufferedWriter的write方法只能接受字符、字符数组和字符串;
- PrintWriter的构造方法更广,不但能接收字符流,也能接收字节
- PrintWriter的println方法自动添加换行,BufferedWriter需要显示调用newLine方法;
- PrintWriter的方法不会抛异常,若关心异常,需要调用checkError方法看是否有异常发生;
- PrintWriter构造方法可指定参数,实现自动刷新缓存(autoflush)流。