一、流的概念

在Java中,流是从源头到目的地的字节的有序序列,存在于Java.io包中,称之为IO(输入输出流)流。

  • IO流的特点:
  • IO流用来处理设备间的数据传输;
  • 流的操作数据分为两种:字节流和字符流;
  • 流按流向分为:输入流和输出流;
  • 根据流相对于程序的另一个端点的不同,分为节点流和过滤流
  • 节点流:以特定源如磁盘文件、内存某区域或线程之间的管道为端点的构造输入输出流,是一种基本的流;如:InputSream和OutputStream
  • 过滤流:以其他已经存在的节点流为端点构造的输入输出流;如:BufferedInputStream和BufferedOutputStream

二、根据流中数据单位的不同,分为字节流和字符流

1、字节流和字符流

首先明确“字节(byte)”和“字符(character)”的大小;

  • 1 byte=8 bit;
  • 1 char=2 byte =16 bit(Java默认UTF-16编码)

字节流就是每次读取1字节的数据;
字符流就是每次读取1字符(2字节)的数据;

除了读取数据的不同之外,读取文件的方式也略有不同,见下图:

Java的io流都是由 java中的io流_Java的io流都是由


字节流是对文件直接操作,而字符流是先把数据读取缓存区,之后再从缓存区获取数据;

做个测试验证下:

Java的io流都是由 java中的io流_字符流_02

1.为什么字符流要设置一个缓存区呢?
答:我们知道,读写会占用IO资源,如果某个程序频繁地对某个资源进行IO,则会大量占用IO资源,如果此时设置一个缓存区,把读写的数据存入缓存区中,下次读取时,直接从缓存区中读取,则大大提高程序的性能;字符流的所有字符操作,都是在内存中形成的,在输出之前把所有字符保存在内存中;

2.何时使用字符流或字节流?
答:设备上的数据无论是图片或者视频,文字,它们都以二进制存储的,二进制的最终都是以一个8位为数据单元进行体现,所以计算机中的最小数据单元就是字节,意味着,字节流可以处理设备上的所有数据,所以字节流一样可以处理字符数据,但只要是处理纯文本数据,就优先考虑使用字符流;

三、字节流

InputStream和OutputStream是字节流的两个顶层父类,提供了输入流类和输出流类的通用API;

1、字节输入流

Java的io流都是由 java中的io流_字符流_03

  • InputStream 是所有的输入字节流的父类,它是一个抽象类;
  • ByteArrayInputStream、StringBufferInputStream、FileInputStream 是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据;
  • PipedInputStream是从与其它线程共用的管道中读取数据;
  • SequenceInputStream是从Enumeration接口中,顺序获取流对象,并读取数据;
  • ObjectInputStream 和所有FilterInputStream 的子类都是装饰流(装饰器模式的主角)

2、字节输出流

Java的io流都是由 java中的io流_字符流_04

  • OutputStream 是所有的输出字节流的父类,它是一个抽象类;
  • ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte数组、和本地文件中写入数据;
  • PipedOutputStream 是向与其它线程共用的管道中写入数据;
  • ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流;

四、字符流

字符流是根据数据编码的不同,而有了对字符进行高效操作的流对象;字符流的类通常以reader和writer结尾;

1、字符输入流

Java的io流都是由 java中的io流_字节流_05

  • Reader是所有字符输入流的父类,它是一个抽象类;
  • BufferedReader提供缓存区,把数据读取到缓存区中;
  • LineNumberReader在 BufferedReader缓存区基础上,提供获取缓存区中数据所在的行号;
  • CharArrayReader创建自定义数组作为其它流的缓冲区;
  • StringReader从字符串中读取字符;
  • FilterReader 的子类都是装饰流;
  • InputStreamReader用指定的编码集,读取文件的数据,并转换成字节,写入的时候通过编码集转换成字符;
  • PipedReader管道流,必须同时使用PipedReader和PipedWriter,PipedWriter作为消费者,PipedReader作为生产者;

2、字符输出流

Java的io流都是由 java中的io流_Java的io流都是由_06

  • Writer是所有字符输出流的父类,它是一个抽象类;
  • CharArrayWriter、StringWriter把char、String类型的参数写进缓存区中;
  • FilterReader 的子类都是装饰流;
  • OutputStreamWriter用指定的编码集,写入文件的字节数据,并根据编码集转换成字符;
  • PipedWriter管道流,必须同时使用PipedReader和PipedWriter,PipedWriter作为消费者,PipedReader作为生产者;