设计模式中巧记I/O
一、I/O
1. I/O操作中的设计模式
概要
- 以设计模式角度,自顶向下理解I/O源码结构
- 理解字节与字符的关系
1.1 装饰者模式(输入流为例)
- 背景:通过继承扩展对象耦合度高,使用装饰者扩展可以在不改变现有结构的情况下,动态地给对象增加额外功能,耦合度底且灵活,一个具体对象可以有多个装饰者
- 字节流

抽象构件:第二行,InputStream接口,定义字节流的基本操作抽象装饰者:第三行,与抽象构建接口是组合关系,动态的传入具体构件。第四行通过扩展抽象构件子类,为具体构件添加新的功能具体构件:第一行,实现抽象构件操作,具体装饰者为每一个具体的构件添加新的职责具体装饰者:第四行,有新职责的具体构建
- 装饰者模式为字节流带来的增强
- 使用
InputStream时,是以一个字节一个字节形式读或写,而BufferedInputStream与BufferedOutputStream为字节流提供了缓冲区,读数据时一次性读取一块数据放到缓冲区中,当缓存区读取完后,输入流会再次填充缓冲区,直到输入流被读取完,缓冲区可以减少IO操作。
- 使用
DataInputStream,从字节流中灵活的读取并重建Java的基本类型与String类型数据
1.2 适配器模式(输入流为例)
- 背景:需要开发的业务功能在组件库中已经存在,但与新的接口规范不兼容,重新开发成本太高,所以使用适配器模式能解决这些问题
- 已有字符流读写接口
Reader与Writer,新的需求是字节流访问数据源,然后由字符流处理
- 为什么使用自符流
- 根本原因:内存中数据操作是以字节为单位(给机器看的);一般持久化到磁盘不同的编码对应不同的字符(给人类看的),也可以以字节形式持久化到硬盘,供软件与硬件阅读。
- 字节流操作单元为字节(8byte)。InputStream中的read()方法,是以
一个字节为单位读取,读到末尾返回-1、它的重载方法read(byte[])内部是通过for循环调用read()实现一次读入一个字节数组,按字节的read()方法的会有频繁IO操作,普通IO模型也会阻塞线程,直到返回一个字节数据或-1,效率太低
- 字节流操作单元为字节(8byte)。InputStream中的read()方法,是以
- 字符流操作单元为Unicode码点(16byte),使用缓存读写。将数据持久化到磁盘 ,使用字节写入会乱码,因为不同语言(汉语、英语等)都有自己对应的编码表,例如英文一个字母可以用一个字节表示,但汉语需要用两个字节,甚至一些特殊符号需要更多字节(Unicode的辅助字符),一个字节一个字节写入很大可能会乱码。所以字符符流会先根据对应的码表将内容写入缓冲区,缓冲区满了持久化到磁盘。使用字符流有两个好处
- 利用缓存读写,避免内存与操作系统频繁IO操作,提高效率
- 写入时指定编码表可以有效避免乱码问题
适配器模式中字符流与字节流

字符流
Reader

Writer

-PS:个人笔记,望读者勘误。本文只例举了字节输入流与字符输入流两种,若读者理解了可以结合源码看输出流中设计模式
设计模式中巧记I/O的更多相关文章
- 巧记 In/hasOwnProperty/for…in/for…of/forEach区别
写在前面 上面提到的这些东西,反复的记忆,反复的忘记.现分享一种巧记方法,有需要,请参考,希望你也过目不忘. 仅提供巧记思路.仅提供巧记思路.仅提供巧记思路. 1. in 用于判断属性是否在对象上(包 ...
- [ACM训练] ACM中巧用文件的输入输出来改写acm程序的输入输出 + ACM中八大输入输出格式
ACM中巧用文件的输入输出来改写acm程序的输入输出 经常有见大神们使用文件来代替ACM程序中的IO,尤其是当程序IO比较复杂时,可以使自己能够更专注于代码的测试,而不是怎样敲输入. C/C++代码中 ...
- [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦
[.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...
- 业务零影响!如何在Online环境中巧用MySQL传统复制技术【转】
业务零影响!如何在Online环境中巧用MySQL传统复制技术 这篇文章我并不会介绍如何部署一个MySQL复制环境或keepalived+双主环境,因为此类安装搭建的文章已经很多,大家也很熟悉.在这篇 ...
- Java设计模式中的单例模式
有时候在实际项目的开发中,我们会碰到这样一种情况,该类只允许存在一个实例化的对象,不允许存在一个以上的实例化对象,我们将这种情况称为Java设计模式中的单例模式.设计单例模式主要采用了Java的pri ...
- java软件设计模式——单例设计模式中的【饿汉式】与 【懒汉式】示例
以下为单例设计模式中的两种经典模式的代码示意: 单例设计模式(spring框架IOC,默认创建的对象都是单例的): 饿汉式: public class SingleClass { private Si ...
- WPF封装控件时 检测是否在设计模式中
原文:WPF封装控件时 检测是否在设计模式中 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Vblegend_2013/article/detail ...
- 简介Python设计模式中的代理模式与模板方法模式编程
简介Python设计模式中的代理模式与模板方法模式编程 这篇文章主要介绍了Python设计模式中的代理模式与模板方法模式编程,文中举了两个简单的代码片段来说明,需要的朋友可以参考下 代理模式 Prox ...
- Python使用设计模式中的责任链模式与迭代器模式的示例
Python使用设计模式中的责任链模式与迭代器模式的示例 这篇文章主要介绍了Python使用设计模式中的责任链模式与迭代器模式的示例,责任链模式与迭代器模式都可以被看作为行为型的设计模式,需要的朋友可 ...
随机推荐
- 环境篇:Virtualbox+Vagrant安装Centos7
环境篇:Virtualbox+Vagrant安装Centos7 1 安装Vagrant Vagrant下载地址:https://www.vagrantup.com/ Vagrant百度网盘:https ...
- C# 在DataGridView中,点击单元格调出 TreeView控件 或 ListBox控件
1.调出 TreeView控件 或 ListBox控件 private void deductGrid1_CellClick(object sender, DataGridViewCellEvent ...
- Oracle job启动与关闭
--查看job下次执行时间以及间隔时间 select * from dba_jobs where job = '774'; --启动job exec dbms_job.run(774); --停用jo ...
- PyTorch专栏开篇
目前研究人员正在使用的深度学习框架不尽相同,有 TensorFlow .PyTorch.Keras等.这些深度学习框架被应用于计算机视觉.语音识别.自然语言处理与生物信息学等领域,并获取了极好的效果. ...
- Ajax-使用教程
运行环境 ajax一定的是运行在网站服务器里面,因此你需要自己配置nodejs服务器 导学:传统的问题还有代理人ajax 传统的http中是又浏览器来做.它在发生和响应的时候网页是不能进行其他操作的 ...
- springboot系列(三)配置文件详解
目录 properties 文件 1.语法 2.优先级 3.自定义数据配置 4.获取自定义数据配置 1.通过prefix获取 yml文件 1.语法 2.优先级 3.自定义数据配置. 4.获取自定义数据 ...
- python学习第四节 迭代器 生成器
1:什么是迭代 可以直接作用于for循环的对象统称为可迭代对象(Iterable). 可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator). 所有的Iterable均可以通 ...
- css过渡和2d详解及案例
css过渡和2d详解及案例(案例在下方,不要着急) 本文重点: 1.在2D变化使用过程中,有些需求需要两种或两种以上的变化同时使用, 值得注意的是尽量把位移变化放在最前面,把其他变化放在最后面,属性值 ...
- Spring Boot创建一个HelloWorld项目
目录 Spring Boot 简介 微服务框架 以前使用spring开发web的方式 Spring Boot 启动器介绍 如何创建一个helloword的SpringBoot项目 Spring Boo ...
- 小白快速使用fetch与后端交互
本人专心后端,但在完成页面碰到了交互,选择了fetch来完成, 总结了一下简单的使用fetch的方法. fetch是纯原生JS与后端交互的方法,请注意,Fetch规格不同于jQuery.ajax(), ...