流的分类

按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
数据流的流向不同分为:输入流,输出流
流的角色的不同分为:节点流,处理流

(抽象基类) 字节流 字符流
输入流 InputStream Reader
输出流 OutputStream Writer

Java的IO流共涉及40多个类,实际上非常规则,都是从如下4个抽象基类派生的。

IO 流体系

a41e6d5908ec4a8d82dc2f5ad9cadb91[0].png
程序中打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件 IO 资源。

注意
定义文件路径时,注意:可以用“/”或者“\”。
在写入一个文件时,如果使用构造器FileOutputStream(file),则目录下有同名文件将被盖。
如果使用构造器FileOutputStream(file,true),则目录下的同名文件不会被覆盖,在文件内容末尾追加内容。
在读取文件时,必须保证该文件已存在,否则报异常。
字节流操作字节,比如:.mp3,.avi,.rmvb,mp4,.jpg,.doc,.ppt
字符流操作字符,只能操作普通文本文件。最常见的文本文件:.txt,.java,.c,.cpp 等语言的源代码。尤其注意.doc,excel,ppt这些不是文本文件。

  1. //使用循环来重复取水的过程
  2. while((hasRead=fis.read(b))>0){
  3. //取出竹筒中的水滴(字节),将字节数组转换成字符串进行输出
  4. System.out.print(new String(b,0,hasRead));
  5. }

缓冲

为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。
abc35d579e1e4021bc189b52122257c3.png
使用方法flush()可以强制将缓冲区的内容全部写入输出流

转换流

转换流提供了在字节流和字符流之间的转换
Java API提供了两个转换流:

InputStreamReader:将InputStream转换为Reader
OutputStreamWriter:将Writer转换为OutputStream

字节流中的数据都是字符时,转成字符流操作更高效。
很多时候我们使用转换流来处理文件乱码问题。实现编码和解码的功能。

标准输入、输出流

System.in和System.out分别代表了系统标准的输入和输出设备
默认输入设备是:键盘,输出设备是:显示器
System.in的类型是InputStream
System.out的类型是PrintStream,其是OutputStream的子类FilterOutputStream 的子类

重定向:通过System类的setIn,setOut方法对默认设备进行改变。

public static void setIn(InputStream in)
public static void setOut(PrintStream out)

打印流

实现将基本数据类型的数据格式转化为字符串输出
打印流:PrintStream和PrintWriter

数据流

为了方便地操作Java语言的基本数据类型和String的数据,可以使用数据流。
数据流有两个类:(用于读取和写出基本数据类型、String类的数据)

DataInputStream 和 DataOutputStream
分别“套接”在 InputStream 和 OutputStream 子类的流上

对象流

ObjectInputStream和OjbectOutputSteam
用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。

序列化:用ObjectOutputStream类保存基本类型数据或对象的机制
反序列化:用ObjectInputStream类读取基本类型数据或对象的机制

ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量

对象的序列化

  • Serializable
  • Externalizable

    随机存取文件流

    RandomAccessFile 声明在java.io包下,但直接继承于java.lang.Object类。并且它实现了DataInput、DataOutput这两个接口,也就意味着这个类既可以读也可以写。

可做用途: 多线程断点下载


从数据来源或者说是操作对象角度看,IO 类可以分为:
image.png