天天看点

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

Java_io体系之概念与整体结构——02

一:写给自己、可无视

       刚从校门走出来时、觉得先上手工作、现在基本能打打酱油的、没有一开始进入社会的那种彷徨了、回头想想自己的程序猿之路。接触java加上填鸭式的三个月培训也就半年出头。很短、整天想着学些时髦的东西、框架、JSON、数据库、操作系统、实际的部署、项目的管理、、、看着大神飞速的代码式原理讲解、一脸的艳羡看着大神使用着各种新东西、各种工具、窗口上飞速敲出来的各种命令的、浏览的各种自己觉得太远的网站、自己写的项目、、、觉得自己真一土鳖、学!今天学点这个、明天学点那个、忙的像个陀螺、静下心来做个总结、看着光标闪半天、不知道自己能写什么、好不容易写出点东西、过短时间回头一看、这是什么?多次无奈之下请教大神、大神说先抛开这些、问你几个问题:你觉得你java基础学的怎么样?我脑中立马浮现的培训的各种内容、有印象、但是讲?不知道讲啥、、你了解的类之间的关系有哪些?脑中立马蹦出继承?引用?、、你知不知道一个request的请求过程?知不知道tomcat的工作原理?哑口无言、、大神没有说什么答案、只是说先把基础东西理解了再说吧。

想想就从IO开始、在学习流的时候、就是先例子、学到一个、当时会用一个流的write、read、内部是怎么实现的?不知道、也没有想过去看看、知道io有很强的对称性、字节流、字符流、具体的内部区别也是一脸茫然、不同的字节流之间有什么区别、为什么会有这样的区别?经常看到好多流都有同样的方法、但是作用却不同、为什么?不知道、、只是知道有区别、使用的时候也就是用一两个熟悉的、还不知道对不对、遇到问题就上网查、查到就copy下来、打完收工、、、、为什么?这不是实现了么、还要为什么干嘛、突然想起来要是某天有人叫你讲讲io、张嘴不知道讲什么、很多类不用的基本都忘的差不多了、知道的也只是仅限于api。

 浮躁的社会、浮躁的心。学的东西是很多、学不完、但是想走的远、觉得还是先吧基础的掌握了吧、还有就是觉得学东西要有目标、东拼西凑的最终结果就是那些最后还是别人的、自己就像一个漏斗。。。废了半天的话只是想留个印记、以后看的时候能知道自己此刻在想些什么。

仅是个人的总结、总有不足之处、望见谅与指正、不胜感激!

二:流的概念与分类:

1.   概念:

关于流的概念版本很多、主要还是理解、下面仅个人理解。

流(Stream)、输入或者输出管道中一串连续不断的有序数据、我们可以用以下情况做联想、有一个水管、水管从水的源头不断的将水抽取到管道中形成一股水流、这种情况下、水管中连续不断的水就是流、相当于IO中输入流管道(水管)从数据源头中读取到输入流管道中的一串有序数据。同样、输出流管道盛放的水也是流、输出流管道可以将水输送到另一个水桶或者别的盛放水的地方、可以把输入流管道的指向称作源(提供流的地方)、吧输出流管道的指向称作目的地(接收流的地方)。流只存在于管道中。

       上面管道中的水就是一串有序数据、也就是流!

而我们平常说的输入输出流、其实是输入流管道、输出流管道、与输入流管道相连的盛放数据的媒介就是流的源头、用于提供输入流管道吸取的流。与输出流管道相连的就是流的目的地、就是接收输出流管道中流的媒介。这些媒介可以是内存、磁盘、网络等。

2.分类:

a. 从流的方向上分为两类:

1、         输入流:从数据源中将数据读取到程序中的流。

2、         输出流:程序将数据写入到目的地的流。

注:输入输出是从某个角度出发去区分的、java中是站在程序的角度来区分流的输入输出的。将数据读取到程序中的就是输入流、将程序中的数据写出去的就是输出流。

b. 从流的数据类型上分为两类:

1、         字节流:以8位的字节形式来读写的流。他们的标志是名称以Stream结尾。InputStream、OutputStream分别是所有字节输入流、字节输出流的父类。

2、         字符流:以字符形式来读写的流。他们的标志是名称以Writer或者Reader结尾。并且Writer、Reader分别是所有字符输出流、字符输入流的父类。

c. 从流的角色可以分成两类:

1、         节点流:从/向一个特定的IO设备(如网络、磁盘)读/写数据的流。也被称为低级流(Low Level Stream)。

2、         处理流:对一个已经存在的流进行连接或者封装、通过封装后的流来进行读/写、也被称为高级流。

三:IO体系结构图

       前面有个引用的IO的设计模式介绍、如果对他有点了解的话对理解IO还是很有帮助的、通过对java类库的学习也可以体会他在设计用到的设计思想、不但能加深理解、还可以提高自己的设计方面修为。这些都是潜移默化的东西、慢慢积累、、

       下面按字节流输入流(InputStream)、字节输出流(OutputStream)、字符输入流(Reader)、字符输出流(Writer)、以及他们之间的对应关系这几个模块来介绍IO整体结构、当然也没有介绍全部的IO类、很少使用的暂不说(下面的图借用了skywang12345的博客IO体系图、归纳的很好、没有再重复去画)。对图中的类进行简单说明、后面会有源码和测试。

1.   InputStream:字节输入流

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

1、         InputStream :字节输入流、是所有字节输入流的父类、为所有字节输入流提供一个标准、和基本的与读取字节有关的方法及简单的实现。

2、         ByteArrayInputStream :字节数组输入流、用于读取其内置缓存字节数组中的字节。内存缓存字节数组中数据的来源是在构建ByteArrayInputStream时传入的字节数组。

3、         PipedInputStream :管道字节输入流、必须与PipedOutputStream(管道字节输出流)结合使用、用于线程之间的通信。

4、         FilterInputStream :过滤器字节输入流、仅仅是重写InputStream方法、为字节输入处理流提供标准。

5、         BufferedInputStream :缓冲字节输入流、装饰类、用于装饰节点类型的字节输入流、为其提供缓冲功能、减少访问次数、提高效率。

6、         DataInputStream :数据字节输入流、装饰类、装饰字节节点输入流、一般与DataOutputStream结合使用、用于读取DataOutputStream写入到目的地中的java基础类型的数据。

7、         FileInputStream :文件字节输入流、以字节的形式将文件中数据读取到程序中、进行下一步操作。

a)      File、既可以表示文件夹、也可以表示具体的文件。这里需要是具体的文件。

b)     文件描述符、可以被用来表示开放文件、开放套接字等。可以通过它来创建对其描述的文件进行读写的流

8、ObjectInputStream :对象字节输入流、与ObjectOutputStream结合使用、用于将使用ObjectOutputStream写入目的地的java对象(一般是javabean)读取到程序中、进行下一步操作。

2.   OutputStream:字节输出流

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

1、         OutputStream:字节输出流、本身是一个抽象类、与InputStream作用一样、为所有字节输出流提供一个标准、定义了一些基本写入字节的方法与简单实现。

2、         ByteArrayOutputStream:字节数组输出流、用于将字节写入到其本身所带的一个内置缓存字节数组中、可将其内置缓存字节数组中的字节转化成字符串到程序中、也可以将它写入到另一个字节输出流中。

3、         PipedoutputStream : 管道字节输出流、在上边介绍过了、必须与PipedInputStream结合使用、用于线程之间的通信。

4、         FilterOutputStream :过滤字节输出流、仅仅重写了父类OutputStream的方法、是字节输出处理流的父类。

5、         BufferedOutputStream : 缓冲字节输出流、装饰类、为低级字节输出流添加缓冲功能、提高效率、减少访问次数。

6、         DataOutputStream : 数据字节输出流、装饰类。用于装饰节点输出流、功能是将java基础类型以一种与系统无关的方式写入到目的地中、可用DataInputStream读取。

7、         PrintStream :字节打印流、装饰类、这是一个功能很强的流、对低级字节输出流进行装饰、提供打印各种数据类型的功能、打印的目的地不仅仅是控制台、可以是文件、内存、网络等、同时还可以指定自动flush功能。

8、         FileOutputStream :文件字节输出流、将字节写入指定的文件中。这里牵扯到的File可以看上面FileInputStream中对他们的简单说明。

9、         ObjectOutputStream :对象字节输出流、用于将java的对象(一般是javabean)写入输出流管道中、存储到某介质中、可使用ObjectInputStream读取被其写入的对象。

3.   InputStream与OutputStream之间的对应关系

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

InputStream与OutputStream及其子类之间有很强的对称性。下图很形象的展现出来他们之间的对应关系。只有PrintStream没有对应的。

字符流的出现、只是让IO体系显得有国际范、不过在某些时候也确实方便了一些、说到实用还是字节流、因为绝大多数数据都是以字节的形式存储在各种存储介质中的。

4.   Reader :字符输入流

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

1、         Reader、意义与InputStream相同、为所有字符输入流提供一个标准、只有基本的读取方法的定义和简单的实现。

2、         CharArrayReader :字符数组输入流、将其内置字符缓存数组中的数据(通过构造方法传入)读取到程序中。内置字符缓存数组中数据的来源是在构造CharArrayReader时传入的字符数组。

3、         PipedReader :管道字符输入流:必须与PipedWriter结合使用、用于线程之间的通信。

4、         FilterReader : 字符过滤流、仅仅简单的重写了Reader中的包含的方法、并且没有具体的直接的子类。个人觉得其意义在于留下一个扩展的点。如同FilterInputStream。

5、         BufferedReader :缓冲字符输入流。装饰类、为低级字符输入流提供缓冲功能、提高效率。并且这里不再继承FilterReader、而是直接继承Reader。

6、         InputStreamReader :字节转换流、将字节流转换成字符流、不仅仅可以将低级字节流输入流转换成字符输入流、还可以将高级字节输入流转换成字符输入流、可以指定字节转成字符时使用的编码、所有具有指定编码或者编码集的字符输入流内部都是调用了此流来转换底层流。

7、         FileReader :文件字符输入流、以字符的形式读取文件中的内容。当文件内容是字节时则可能会有问题、对其牵扯到的File不再唠叨。

5.   Writer :字符输出流

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

1、         Writer :字符输出流、是所有字符输出流的父类。与OutputStream意义一样、提供一个标准、一些基本写入的方法和简单的实现。

2、         CharArrayWriter : 字符输出流、用于将字符写入其内置缓存字符数组中。可以将写入的字符缓存数组转换成字符串或者写入其他字符输出流中。

3、         PipedWriter : 管道字符输出流、必须与PipedReader结合使用、用于线程之间的通信。

4、         BufferedWriter : 缓存字符输出流、用于装饰低级字符输出流、为其提供缓冲功能、提高效率。

5、         OutputStreamWriter :字节输出流转换成字符输出流、用于将字节输出流转化成字符输出流。可以使用指定编码转化。为提高效率、通常使用BufferedWriter对其包装。

6、         FileWriter :文件字符输出流、继承OutputStreamWriter、用于将字符写入到指定文件中。File也不再唠叨。

7、         PrintWriter :字符打印流、同样很强大、可以将各种数据以字符的形式打印到指定目的地中、本身也是个装饰流。但是flush与PrintStream有区别。

6.   Reader与Writer之间的对应关系

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

同样:Reader与Writer之间的对应关系也很明确。只有PrintWriter没有对应的输入流。且因为其直接操作的对象是字符、所以没有那么多复杂的装饰和继承关系。结构更加明确。

7.   字节向字符转换的编码过程

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

8.   字节向字符转换的解码过程

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

这里要注意的是: javaIO中只有将字节流转换成字符流的方法、没有字符流转换成字节流的方法。原因很简单、没有必要。

9.   输入字节流、输入字符流之间对应关系

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

10. 输出字节流、输出字符流之间对应关系:

Java_io体系之概念与整体结构——02Java_io体系之概念与整体结构——02

四:总结

       流的理解还是有点饶人的、要弄清IO、首先就要弄清他的整体体系、不仅仅是输入输出、字节、字符、还要清楚他们之间的继承关系、使用的区别、多方面进行对比、多动手试试差异。

字节与字符流之间的本质区别:仅仅是操作的单元不一样!有些数据既可以使用字节流、又可以使用字符流、因为这些数据既可以用字符表示也可以用字节表示。比如上面绝大多数的流、有些只能用字节流、比如ByteArrayInputStream、ByteOutputStream、DataInputStream、DataOutputStream、ObjectInputStream、ObjectOutputStream、因为他的操作对象只能是字节、并且不能将这些字节转换成字符。