Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。
标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流等等,java中将输入输出抽象称为流,就好像水管,将两个容器连接起来。将数据冲外存中读取到内存中(供Java程序使用)的称为输入流,将数据从内存写入外存中的称为输出流。
流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
流的分类:
流的分类,Java的流分类比较丰富,刚接触的人看了后会感觉很晕。流分类的方式很多:
1、按照输入的方向分,输入流和输出流,输入输出的参照对象是Java程序。
2、按照处理数据的单位不同分,字节流和字符流,字节流读取的最小单位是一个字节(1byte=8bit),而字符流一次可以读取一个字符(1char = 2byte = 16bit)。
3、按照功能的不同分,分节点流和处理流,节点流是直接从一个源读写数据的流(这个流没有经过包装和修饰),处理流是在对节点流封装的基础上的 一种流,FileInputStream是一个节点流,可以直接从文件读取数据,但是BufferedInputStream可以包装 FileInputStream,使得其有缓冲功能。
流的类结构图:
Java中“流”的概念与简介
字节流与字符流:
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。 字节流和字符流的区别:
读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
结论:只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。
这里需要提到的一句是:一个英文字符的长度是1byte,而汉字的长度是2byte. 如果我们把英汉混合的文档统一按照字节流处理,就会出现分割混乱,出现乱码。这是,我们需要使用字符流来处理。这就是为什么在处理文档的时候,都要把inputstream放到FileReader中。
方向性:
流分为输入流和输出流。但这都是相对的。特别是在Hadoop的序列化时,总是不知道到底使用输入流还是输出流。这里,我们可以做个区分:
序列化,就是把数据做字节流处理。而字节流只是一种存储形式。他不会被程序识别,需要把字节流反序列化为java识别的对象,才可以被java程序识别。所以,序列化就是字节流化,就是从java代码或内存中输出到外存。而反序列化就是对象化,就是从外存中将字节流数据转化为程序识别的对象。