[四] JavaIO之类层次体系结构横向比对

IO家族类层次体系结构横向匹配

上一篇文章中主要介绍了JavaIO流家族的整体设计思路,简单回顾下

基本逻辑涉及数据源 流的方向,以及流的数据形式这三个部分的组合

按照流的数据形式和流的方向,组合而来了四大家族,分别是:

InputStream/OutputStream Reader/Writer

数据源与四大家族的组合构成了IO流的基本功能

数据源形式

InputStream

OutputStream

Reader

Writer

ByteArray(字节数组)

ByteArrayInputStream

ByteArrayOutputStream

File(文件)

FileInputStream

FileOutputStream

FileReader

FileWriter

Piped(管道)

PipedInputStream

PipedOutputStream

PipedReader

PipedWriter

Object(对象)

ObjectInputStream

ObjectOutputStream

String

StringBufferInputStream

StringReader

StringWriter

CharArray(字符数组)

CharArrayReader

CharArrayWriter

扩展功能基本通过装饰器模式实现

扩展功能点

InputStream

OutputStream

Reader

Writer

Data(基本类型)

DataInputStream

DataOutputStream

Buffered(缓冲)

BufferedInputStream

BufferedOutputStream

BufferedReader

BufferedWriter

LineNumber(行号)

LineNumberInputStream

LineNumberReader

Pushback(回退)

PushbackInputStream

PushbackReader

Print(打印)

PrintStream

PrintWriter

从上面的列表应该可以看得出来,对于IO体系中的主要的一些类和接口

我们只需要明确两点,就能够更加深入的了解他们

1.针对于各种数据源,四大家族的处理逻辑

2.扩展功能点的含义

注意:

很多IO的成员并不操作磁盘上的文件

比如ByteArrayInputStream和ByteArrayOutputStream  接下来我们还会详细的介绍到

他们并不直接操作持久化的数据(存储在磁盘上的),还有不少其他的也都不是的

他们跟IO有什么关系?为什么他们要实现流的接口?

此处我想要提醒的是,

对于我们程序设计语言来说,IO 表示的是对数据的操纵,数据有读写

IO代表的是一类可读可写行为类似的事物,而不是指从磁盘上读取文件

为什么不是有一个单纯的类去进行对于字节数组的操作呢,为什么非要跟IO挂钩沾边?

首先,这并不是不可以,

的确是可以构造一个跟IO体系结构没关系的字节数组

来操纵类进行字节数组的读写

可是,他的行为显然跟IO非常的类似,在定义一套不同的接口显然增加开发者使用成本

再者,不管从哪里读 ,本身也仍旧是输入输出的问题

而且,针对不同的数据源提供一致性的接口,这也非常的符合面向接口的编程规范

所以,一句话,不要把IO狭隘地理解为操作磁盘上的文件.数据.

IO是输入与输出,是读与写的代名词

IO数据源应用

ByteArray(字节数组)

字节数组,毫无疑问,不会应用在字符家族里面 他应用于 ByteArrayInputStream   以及  ByteArrayOutputStream 他的内部包含一个 字节数组    byte buf[] ByteArrayInputStream  以及  ByteArrayOutputStream  内部维护了一个byte buf[] 会将数据读取到这个字节数组(缓冲区) 或者将数据写入到这个字节数组(缓冲区) 他们维护的是这个内部的字节数组本身,并不会写入文件

这两个类本质就是操纵字节数组,提供对字节数组的读取与写入它的本质如同文件一样,都是用来存储数据只不过是数据存在于内存中而已通过将数据封装到内部的字符数组中,可以提供IO一致性的接口

ByteArray  仅仅应用与字节流

File(文件)

前面说过,File 是最常见的一种数据形式所以对IO提供针对文件的操作非常合理我们知道,所有的数据存储最终都是字节的形式但是对于文件的操作又是如此的频繁和重要所以,针对于字符的输入输出也提供了对应的处理不过还是那句话,最终文件都是字节形式存储,所以,对于字符文件,自然需要进行编码与解码FilterReader每一次的读取都意味着一次解码FilterWriter每一次的写入都意味着编码

既然是文件,我们前面介绍过File类File类的构造主要由路径名或者文件描述符所以对于文件的输入输出相关的IO操作,自然可以通过  路径名  文件描述符  或者File 本身作为目标对象也就是说构造函数的参数一般都是这三者之一

对于文件的操作是实实在在的操作文件本身File 四大家族都有应用

Piped(管道)

管道的概念,不是来自于java io很早前就有此概念含义非常明朗,就如同他的名字一样,管道,好像两个水管连接起来,形成一个通道这个通道是直接连接的,并不会再跑到别的地方去弯弯绕管道流的主要作用是可以进行两个线程间的通讯既然主要作用进行线程间的通讯,他就是传输数据使用的IN 字节数组缓存数据,OUT使用IN对象

管道在四大家族中都有应用

Object

ObjectInputStream 和 ObjectOutputStream 的作用是,对基本数据和对象进行序列化操作支持 ObjectOutputStream对象能提供对“基本数据或对象”的持久存储 ObjectInputStream,读取出这些“基本数据或对象” 只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能被ObjectInputStream/ObjectOutputStream所操作

序列化自然不可能就只有字符,所以Object仅仅针对字节家族

String

提供了对String类型的支持reader读取到Stringwriter写入到StringBuffer

StringBufferInputStream  已经不推荐使用了所以,后续可以认为String仅仅支持字符家族

CharArray

类似ByteArray,也是提供对字符数组的支持操纵内存数据

字符数组仅仅支持字符家族

其实可以看得出来,只有File才是真正跟磁盘文件相关的

其他的数据源形式都是操作内存数据

IO扩展功能应用

Data(基本类型)

Data是对基本数据类型的支持针对于DataOutputStream写出的数据文件可以使用DataInputStream进行读取也就是说是一种特殊形式的文件

他们底层依赖的还是字节流  通过继承FilterInputStream 和 FilterOutputStream使用其中的InputStream in   以及  OutputStream out这两个对象是通过构造方法传递进来的

Buffered(缓冲)

缓冲也就是为了减少读取的频率,设置一个缓冲区缓冲的概念到处都是,所以缓冲应用于四大家族

LineNumber(行号)

LineNumber是针对输入的所以存在于LineNumberInputStream和LineNumberReader不过对于字节流的LineNumberInputStream 已经弃用

LineNumberReader是一个跟踪行号的缓冲字符输入流也很显然,流都是顺序读取不能回退的,所以想要读取行号自然要借助于缓存他的实现继承BufferedReader 也很好理解

Pushback

Pushback 回退,也就是读取了一个字符,然后再次把它放回到流中所以是针对输入的PushbackInputStream  PushbackReader 也是借助于内部的缓存

Print(打印)

主要是为了提供数据打印的便利性

打印自然是针对于输出的 PrintStream  PrintWriter

本文从数据源以及扩展功能点的角度,再次分析了IO类库的整体设计

虽然上一篇文章中对于所有的基本功能点以及扩展功能点已经做了一个介绍

本文再次提及是为了着重强调,数据源与扩展功能点在类层次结构中涉及的重要性

只有彻底明确了数据源以及扩展功能点的逻辑

才能彻底理解整个IO类库架构设计

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博客

Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.h...

943
来自专栏IT笔记

聊一聊生产环境中如何动态监听配置文件变化并重载

上一篇,我们谈到Java中的几种读取properties配置文件的方式,但是在生产环境中,最忌讳的就是重启应用了。比如某个系统的路径常量或者接口变更,需要线上及...

40911
来自专栏Danny的专栏

【SpringDataJPA】——SpringDataJPA入门实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

1232
来自专栏Hongten

java开发_模仿百度文库_SWFTools_源码下载

在之前有做了一篇文章:java开发_模仿百度文库_OpenOffice2PDF_源码下载

1012
来自专栏JavaEE

java基础知识02

1、String字符串: 字符串一旦被初始化,就不可以被改变,存放在方法区中的常量池中。用length()方法获取长度。

722
来自专栏LinkedBear的个人空间

唠唠SE的IO-04——缓冲输入输出流 原

BufferedOutputStream和BufferedOutputStream类可以通过减少读写次数来提高输入和输出的速度。

1033
来自专栏向治洪

Kotlin 1.2 新特性

在Kotlin 1.1中,团队正式发布了JavaScript目标,允许开发者将Kotlin代码编译为JS并在浏览器中运行。在Kotlin 1.2中,团队增加了在...

22010
来自专栏10km的专栏

java:学习commons-configuration2读取配置文件xml,properties

commons-configuration是apache为java应用程序提供的一个通用的配置文件管理接口,可以支持多种配置文件格式: Properties ...

3805
来自专栏转载gongluck的CSDN博客

UNPv13:#第3章#套接字编程简介

IPv4套接字地址结构 POSIX规范只要求3个字段:sin_family、sin_addr和sin_port。 #include <netinet/in.h>...

3415
来自专栏好好学java的技术栈

并发基础篇(二):Thread类的API总结

1164

扫码关注云+社区