【JAVA基础篇】IO流

一、流的概念

“对语言设计人员来说,创建好的输入/输出系统是一项特别困难的任务。”

                                                                                                                       ――《Think in Java》

无论是系统、还是语言的设计中IO的设计都是异常复杂的。面临的最大的挑战一般是如何覆盖所有可能的因素,我们不仅仅要考虑文件、控制台、网络、内存等不同的种类,而且要处理大量的不同的读取方式,如:顺序读取、随机读取,二进制读取、字符读取,按行读取、按字符读取……

为了解决输入/输出问题,创建了Java IO体系,并且提出了流的概念。

如何理解流的概念?联想一下现实生活中水流,自来水公司通过管道将水送入千家万户,数据相当于现实生活中的水,JAVA中的流相当于现实生活中的管道。在Java中,流代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象,流的作用是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

ps:当面试问到你对流的理解时,可以拿生活中的自来水来做对比或者从面对对象的角度来讨论。

二、Java IO体系

1、基于字节的IO操作

2、基于字符的IO操作

从上图可以看到,整个Java IO体系都是基于字节流(InputStream/OutputStream) 和字节流(Reader/Writer)作为基类,根据不同的数据载体或功能派生出来的。

3、分类

按照数据单位来分:字节流、字符流

按照方向分:输入流、输出流

按照功能来分:节点流、处理流(直接与底层文件资源连接的称为节点流,对节点流进行包装从而完成更高级功能的称为处理流,处理流在构造时须为其指定一个节点流.)

三、扩展

下面我们来看一下JDK1.8的源代码

3.1、源代码

3.1.1、InputStream

    public abstract int read() throws IOException;//从输入流中读取一个字节(值0-255)并返回,子类必须提供此方法的实现,如果到达了流的末尾,则返回-1public int read(byte b[]) throws IOException {return read(b, 0, b.length);}/*** 实际上还是调用read()方法,将读到的内容放到字节数组中b,返回-1(已读到流的末尾)或者实际读取的字节数*/public int read(byte b[], int off, int len) throws IOException {if (b == null) {throw new NullPointerException();} else if (off < 0 || len < 0 || len > b.length - off) {throw new IndexOutOfBoundsException();} else if (len == 0) {return 0;}int c = read();if (c == -1) {return -1;}b[off] = (byte)c;int i = 1;try {for (; i < len ; i++) {c = read();if (c == -1) {break;}b[off + i] = (byte)c;}} catch (IOException ee) {}return i;}/*** 跳过n个字节,实际上还是调用read()方法,所以read()方法很关键,返回实际跳过的字节数*/public long skip(long n) throws IOException {long remaining = n;int nr;if (n <= 0) {return 0;}int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);byte[] skipBuffer = new byte[size];while (remaining > 0) {nr = read(skipBuffer, 0, (int)Math.min(size, remaining));if (nr < 0) {break;}remaining -= nr;}return n - remaining;}

上面的源码和注释分析了read方法和skip的作用。

3.1.2、OutputStream

    public abstract void write(int b) throws IOException;//将指定字节写入输出流,只会写入低8位,高的24位会被忽略,因为一个字节只有8个bit位public void write(byte b[]) throws IOException {write(b, 0, b.length);}public void write(byte b[], int off, int len) throws IOException {if (b == null) {throw new NullPointerException();} else if ((off < 0) || (off > b.length) || (len < 0) ||((off + len) > b.length) || ((off + len) < 0)) {throw new IndexOutOfBoundsException();} else if (len == 0) {return;}for (int i = 0 ; i < len ; i++) {write(b[off + i]);}}

3.1.3、Reader

    abstract public int read(char cbuf[], int off, int len) throws IOException;//将字符读入数组,此方法可能会发生阻塞,返回-1或者读入的字符数public int read(char cbuf[]) throws IOException {return read(cbuf, 0, cbuf.length);}/*** 将字符读入字符缓冲区*/public int read(java.nio.CharBuffer target) throws IOException {int len = target.remaining();char[] cbuf = new char[len];int n = read(cbuf, 0, len);if (n > 0)target.put(cbuf, 0, n);return n;}/*** 读取单个字符*/public int read() throws IOException {char cb[] = new char[1];if (read(cb, 0, 1) == -1)return -1;elsereturn cb[0];}

3.1.4、Writer

    abstract public void write(char cbuf[], int off, int len) throws IOException;//将字符数组的一部分写入到输出流/*** 将指定字符写入到输出流*/public void write(int c) throws IOException {synchronized (lock) {if (writeBuffer == null){writeBuffer = new char[WRITE_BUFFER_SIZE];}writeBuffer[0] = (char) c;write(writeBuffer, 0, 1);}}/*** 将字符数组的所有内容写入到输出流*/public void write(char cbuf[]) throws IOException {write(cbuf, 0, cbuf.length);}/*** 将字符串的所有内容写入到输出流*/public void write(String str) throws IOException {write(str, 0, str.length());}/*** 将字符串的部分内容写入到输出流*/public void write(String str, int off, int len) throws IOException {synchronized (lock) {char cbuf[];if (len <= WRITE_BUFFER_SIZE) {if (writeBuffer == null) {writeBuffer = new char[WRITE_BUFFER_SIZE];}cbuf = writeBuffer;} else {    // Don't permanently allocate very large buffers.cbuf = new char[len];}str.getChars(off, (off + len), cbuf, 0);write(cbuf, 0, len);}}

3.2、NIO

对IO的概念有基本的了解之后,我们再来了解一下JAVA中类似的概念NIO。由于本文主要介绍IO的概念,所以对NIO的介绍会很浅显,后面会有专门的文章来介绍NIO。

NIO( New Input/ Output)一种同步非阻塞的IO模型。同步是指线程不断轮询IO事件是否就绪,非阻塞是指线程在等待IO的时候,可以继续其他任务。同步的核心是Selector,Selector替代了线程本身去轮询IO事件,避免了阻塞的同时也减少了不必要的线程消耗;非阻塞的核心是通道和缓冲区,当IO事件就绪时,可以通过写到缓冲区,保证IO的成功,而无需线程阻塞式的等待。

NIO和IO的主要区别

IONIO
面向流面向缓冲
阻塞IO非阻塞IO
选择器

关于通道、缓冲区和选择器的实现参考https://blog.csdn.net/forezp/article/details/88414741

参考:

  1. https://blog.csdn.net/qq_36962144/article/details/79815457
  2. https://www.cnblogs.com/ylspace/p/8128112.html
  3. https://www.cnblogs.com/fysola/p/6123947.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/530410.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringMVC注解

一&#xff0c;RequestMapping 可以用在类和方法上 1.1 作用&#xff1a; 将客户端请求映射到可匹配的类和方法中 1.2 属性&#xff1a; name 给映射指定一个名字 path(同value相同&#xff09; 请求的url&#xff0c;path{"/mixedAttribute1","/mixedA…

【JAVA基础篇】运算符

一、表达式 表达式由运算符和操作数组成 例如&#xff1a; 5 num1 num1num2 sumnum1num2 二、运算符分类 算数运算符、赋值运算符、关系运算符、逻辑运算符、条件运算符、位运算符 三、算数运算符 四、赋值运算符 格式&#xff1a;变量表达式 例如&#xff1a;int n3…

a4纸网页打印 table_打印模板不愁人,你还在打印单调的A4纸吗?

软件介绍早在几年前&#xff0c;社会上就已经开始了数字化、无纸化的推广&#xff0c;但是就算再怎么无纸化&#xff0c;纸张还是有它必要的存在&#xff0c;在工作、学习过程中&#xff0c;打印的需求也必不可少的。但是一般的打印都是比较平庸的&#xff0c;要做会议记录&…

IP地址、子网掩码、网关、默认网关、DNS的理解

IP地址 Internet上为了区分数以亿计的主机而给每个主机分配一个专门的地址&#xff0c;通过IP地址可以访问到每台主机。 子网掩码 子网掩码又称网络掩码、地址掩码、子网络遮罩。它是用来指明一个IP地址哪些位标识的是主机所在的子网&#xff0c;以及哪些位标识的是主机的位…

上证指数30年k线图_技术预判2020:上证指数要突破3500点才会“井喷”

2019年的行情很快就要收官了&#xff0c;截止目前&#xff0c;上证指数今年的涨幅是20.5%&#xff0c;不过可能有部分投资者今年的收益率还没达到大盘指数的平均水平。不管怎样&#xff0c;今年很快就要翻篇了&#xff0c;关键是看2020年股市能不能迎来更好的行情了。而总结得失…

【JAVA基础篇】基本数据类型及自动类型转换

一、8种基本数据类型以及占用内存空间大小 boolean 1byte或4byte byte 8bit/1byte char 16bit/2byte short 16bit/2byte float 32bit/4byte int 32bit/4byte long 64bit/8byte double 64bit/8byte 二、自动类型转换 …

的优缺点_浅谈桉木家具的优缺点

家具现在的材质是有很多的&#xff0c;木质的&#xff0c;石材的&#xff0c;还有真空充气的&#xff0c;都是很不错的类型。桉木家具是现在很多人都喜欢的一种材质&#xff0c;但是很多人对桉木家具的优缺点不是很清楚&#xff0c;为了能够让大家更加清楚的了解桉木家具&#…

【算法篇】递归

一、递归的概念 程序调用自身的编程技巧称为递归。 递归的核心思想就是将一个大规模复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。 二、递归的优点 使用递归的好处是只需要少量的代码就可以描述出求解问题过程中多次重复的计算&#xff0c;大大减少了程序…

客户说发货慢怎么回复_女生微信说身体不舒服怎么回复关心她?

当你不在女生身边&#xff0c;女生微信给你说身体不舒服&#xff0c;肯定需要说点话来安慰她了。多喝热水肯定是不行了&#xff0c;一点用处都没有&#xff0c;还会让女生觉得你根本不重视她&#xff0c;是在敷衍她&#xff0c;那女生微信说身体不舒服怎么回复关心她呢&#xf…

【算法篇】八种内排序算法

常用的八种内排序算法分别是&#xff1a; 交换排序&#xff1a;冒泡排序、快速排序选择排序&#xff1a;简单选择排序、堆排序插入排序&#xff1a;直接插入排序、希尔排序归并排序基数排序 内排序巧记&#xff1a;选(选择)舰(简单选择)队(堆)的时候脚(交换)毛(冒泡)快(快速)&…

数据分析专题报告范文6篇_小学生看图写话范文:小熊玩跷跷板?(6篇),让孩子参考练习...

​范文01&#xff1a;小熊跷跷板一天&#xff0c;天气晴朗&#xff0c;胖乎乎的小熊和小白兔一起玩跷跷板。小熊一屁股坐在地上&#xff0c;小白兔说&#xff1a;“啊&#xff01;我有恐高症哇&#xff01;”小熊说&#xff1a;“我比你重&#xff0c;所以你没有办法把我翘起来…

PL/SQL

1 PL/SQLPL/SQL:过程化SQL语言&#xff08;Procedural Language/SQL&#xff09;。PL/SQL是Oracle数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编程语言的特点&#xff0c;所以PL/SQL把数据操作和查询语句组织在PL/SQL代码的过程性单元中&#xff0c;通过逻辑判断、循环…

20sccm_SCCM 2012安装图解教程(一步一步详细步骤)

本系列文章的环境架构如下图所示&#xff1a;所有服务器安装的操作系统都是windows Server 2008 R2 中文企业版。计算机名软件、版本及角色SC-DC.SC.COMwindows Server 2008 R2 Enterprise /Active Directory 2008 R2SC-SQL.SC.COMSQL Server 2008 R2 EnterpriseSC-SCCM.SC.COM…

【Java中级篇】Dom4j解析xml数据

一、依赖 <dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency> 二、test.xml <?xml version"1.0" encoding"UTF-8"?> <students>…

redis 附近的人_使用redis—geo api实现搜索附近的人,自己写的一个composer包

安装如果是应用在项目当中的话找到根目录&#xff0c;需要和 composer.json同级composer require gaopengfei/redis_lbs基本操作初始化require_once __DIR__./vendor/autoload.php;$lbs new \LBS\Services\LBSService();添加$add_params [[name > yabao_road,long > 11…

【Java中级篇】使用zxing生成二维码

一、pom.xml添加依赖 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.1.0</version></dependency><dependency><groupId>com.google.zxing</groupId><artifa…

微信小程序弹出框竖向滚动_微信小程序 解决自定义弹出层滑动时下层页面滚动问题...

WXML将整个底层页面使用 scroll-view 包裹起来&#xff0c;设置 scroll-y 当显示弹出层的时候为 true&#xff0c; 闭关弹出层的时候为 falseWXSSPage 设置为绝对定位&#xff0c;宽高各百分之百 &#xff0c; scroll-view 高度 百分之百Page{position: absolute;width: 100%;h…

win10环境安装使用svn客户端和服务端

一、下载安装包 安装包下载传送门http://subversion.apache.org/packages.html 无法下载的童鞋去百度云下载 链接&#xff1a;https://pan.baidu.com/s/1EuGohoZKIPmRvynp5-Subw 提取码&#xff1a;ohna 链接&#xff1a;https://pan.baidu.com/s/1EJrd5DzGCBE4rRfdhuno6Q …

openglshader实现虚拟场景_opengl – 如何使用GLSL着色器将径向模糊应用于整个场景?...

我在GLSL中有一个径向模糊着色器,它采用纹理,对其进行径向模糊,并将结果呈现给屏幕.这个工作很好,到目前为止.问题在于,它将径向模糊应用于场景中的第一个纹理.但是我实际上想做的就是将这个模糊应用于整个场景.实现此功能的最佳方式是什么&#xff1f;我可以只使用着色器,还是…

记一次尴尬的面试

昨天信达雅公司邀请我去平安面试&#xff0c;然后我今天10点到科技信息中心&#xff0c;等了接近20分钟才有人过来接我。 第一个环节是机试 40个题目&#xff0c;主要是选择题&#xff0c;花了40分钟结束战斗&#xff0c;总分100得了75分&#xff08;手机快没电了&#xff0c…