IO 模型

传统 IO读写

       磁盘IO主要的延时是由(以15000rpm硬盘为例): 机械转动延时(机械磁盘的主要性能瓶颈,平均为2ms) + 寻址延时(2~3ms) + 块传输延时(一般4k每块,40m/s的传输速度,延时一般为0.1ms) 决定。(平均为5ms)

 /**
* 传统的IO读取
* @param oriStr
* @param destStr
*/
public void customRead(String oriStr,String destStr){
FileInputStream in = null;
FileOutputStream os = null;
try {
in = new FileInputStream(oriStr);
os = new FileOutputStream(destStr);
//一次读取1K 数据
byte[] bytes = new byte[1024];
while(in.read(bytes)!=-1){
os.write(bytes);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
in.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 带缓冲区的IO读取
* @param oriStr
* @param destStr
*/
public void bufferRead(String oriStr,String destStr){
BufferedInputStream in = null;
BufferedOutputStream os = null;
try {
in = new BufferedInputStream(new FileInputStream(oriStr));
os = new BufferedOutputStream(new FileOutputStream(destStr));
//一次读取1K 数据
byte[] bytes = new byte[1024];
while(in.read(bytes)!=-1){
os.write(bytes);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
in.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

QA  很多人看了上述2段代码后,可能要反驳啦,customRead有缓存啊,不是一次性读取1024个字节到byte数组了吗

QA  bufferRead 为啥一定比customeRead 速度快

其实要理解上面2个问题,很简单,

①:fileInputStream.read(byte[]) 是一个骗人的方法,他是通过循环操作调用read()方法,每次读取一个字节,然后填满byte数组。

②:BufferedInputStream.read(byte[]) 他是预先从磁盘读取最大8K的数据,然后保存在本地的一个叫buf 数组中,后面读取数据的时候直接从这个buf中获取

fileInputStream 每次从磁盘获取数据,BufferedInputStream 每次才从本地缓存拿数据,一目了然,BufferedInputStream 明显快多啦(源码不是很复杂,有兴趣的朋友可以看看源码就知道啦)

网络IO

    网络IO主要延时由: 服务器响应延时 + 带宽限制 + 网络延时 + 跳转路由延时 + 本地接收延时 决定。(一般为几十到几千毫秒,受环境干扰极大),考虑到网络IO瓶颈,就有很多传输模型,BIO,NIO等等 在这些模型中就不得不提 ByteBuffer,

那ByteBuffer 是啥,其实这个东西经常用在网络传输NIO模型上,网络传输为了提高效率,不可能一个一个在磁盘上读取,那么需要读取一块数据存储到内存里,ByteBuffer(ByteBuffer内部维护一个byte[],是不是很熟悉,这个套路)就是应用缓存,负责在内存中保存读取的那一整块数据

//伪代码
public void nioRead() {
FileChannel channel=null;
try{
RandomAccessFile raf=new RandomAccessFile("src/exp_io.txt","rw");
//获取通道
channel=raf.getChannel();
if(0==raf.length()){
return;
}
//分配缓存空间
ByteBuffer buffer=ByteBuffer.allocate((int)raf.length());
byte [] bytes=new byte[(int)raf.length()];
//将数据写入缓存
int bytesRead=channel.read(buffer);
int i=0;
while (bytesRead!=-1){
buffer.flip();
while (buffer.hasRemaining()){
//从缓存读取数据
bytes[i]=buffer.get();
i++;
}
//将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面
//现在向缓存中写入数据时不会覆盖未读的数据
buffer.compact();
bytesRead=channel.read(buffer);
}
System.out.println(new String(bytes));
}catch (Exception e){ }finally {
try{
if (channel!=null){
channel.close();
}
}catch (Exception e){ }
}
}

  

总结

java 为提高IO读写的效率,就一个办法,想办法一次性多读取数据,然后缓存起来。其实ByteBuffer 和BufferedInputStream的根本方法都是一致的,就是搞一个本地的应用缓存,来解决IO瓶颈。

考虑一个问题 ByteBuffer 是堆内分配内存,如果,我直接用堆外内存(减少系统缓存copy到应用缓存中)作为应用缓存,那么能不能提高IO瓶颈。(netty的套路,有兴趣大家可以研究一下哈)

参考资料

网络IO和磁盘IO详解 https://www.cnblogs.com/sunsky303/p/8962628.html

BufferByte用法小结 https://blog.csdn.net/mrliuzhao/article/details/89453082

聊聊 传统IO和网络IO的更多相关文章

  1. 多路复用 阻塞/非阻塞IO模型 网络IO两个阶段

    1.网络IO的两个阶段 waitdata copydata send 先经历:copydata阶段 recv 先经历:waitdata阶段 再经历 copydata阶段 2.阻塞的IO模型 之前写的都 ...

  2. 磁盘 IO 和网络 IO 该如何评估、监控、性能定位和优化?

    生产中经常遇到一些IO延时长导致的系统吞吐量下降.响应时间慢等问题,例如交换机故障.网线老化导致的丢包重传:存储阵列条带宽度不足.缓存不足.QoS限制.RAID级别设置不当等引起的IO延时. 一.评估 ...

  3. Socket-IO 系列(一)Linux 网络 IO 模型

    Socket-IO 系列(一)Linux 网络 IO 模型 一.基本概念 在正式开始讲 Linux IO 模型前,先介绍 5 个基本概念. 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器, ...

  4. 阿里、腾讯热门面试题:聊聊Unix与Java的IO模型?(含详细解析)

    众所周知 如果去百度.腾讯等一线大厂面试,一定会深入考候选人的基础技术功底,其中尤为关键和重视的就是IO相关的技术和知识. 而要搞明白IO相关的概念,首先就得弄清楚同步与异步,阻塞与非阻塞到底是什么意 ...

  5. 我对网络IO的理解

    Unix/Linux系统下IO主要分为磁盘IO,网络IO,我今天主要说一下对网络IO的理解,网络IO主要是socket套接字的读(read).写(write),socket在Linux系统被抽象为流( ...

  6. 网络io控制器

    网络io控制器 网络io控制器 ZLAN6842,ZLAN6844是8路远程网络IO控制器.含有8路DI.8路DO,8路AI输入.其中DI支持干节点和湿节点,带光耦隔离:DO为继电器输出,具有5A 2 ...

  7. 漫谈Java IO之普通IO流与BIO服务器

    今天来复习一下基础IO,也就是最普通的IO. 网络IO的基本知识与概念 普通IO以及BIO服务器 NIO的使用与服务器Hello world Netty的使用与服务器Hello world 输入流与输 ...

  8. 并发编程 - IO模型 - 1.io模型/2.阻塞io/3.非阻塞io/4.多路复用io

    1.io模型提交任务得方式: 同步:提交完任务,等结果,执行下一个任务 异步:提交完,接着执行,异步 + 回调 异步不等结果,提交完任务,任务执行完后,会自动触发回调函数同步不等于阻塞: 阻塞:遇到i ...

  9. 5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO

    POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...

随机推荐

  1. Java安全之Commons Collections5分析

    Java安全之Commons Collections5分析 文章首发:Java安全之Commons Collections5分析 0x00 前言 在后面的几条CC链中,如果和前面的链构造都是基本一样的 ...

  2. ABP 数据访问 - IRepository 仓储

    ABP系列,这个系列来的比较晚,很多大佬其实已经分析过,为什么现在我又来一轮呢? 1.想自己来完整的学习一轮ABP 2.公司目前正在使用ABP,准备迁移Core 基于以上的目的,开始这个系列 ABP ...

  3. Vulnhub DC3

    靶机简介 C-3是另一个专门建造的易受攻击的实验室,目的是获得渗透测试领域的经验.与以前的DC版本一样,这个版本是为初学者设计的,尽管这次只有一个标志,一个入口点,根本没有线索.Linux技能和熟悉L ...

  4. 【译】Ringbahn的两个内存Bug

    原文链接:https://without.boats/blog/two-memory-bugs-from-ringbahn/ 原文标题:Two Memory Bugs From Ringbahn 公众 ...

  5. python数学math和random模块

    math模块 关注公众号"轻松学编程"了解更多. 在使用math模块时要先导入 # 导入模块 import math 1.math.ceil(num) 对num进行向上取整 num ...

  6. 重要 | Spark和MapReduce的对比,不仅仅是计算模型?

    [前言:笔者将分上下篇文章进行阐述Spark和MapReduce的对比,首篇侧重于"宏观"上的对比,更多的是笔者总结的针对"相对于MapReduce我们为什么选择Spar ...

  7. P6064 [USACO05JAN]Naptime G

    最近做了多少道 usaco 了,连 FJ 都认识我了呀 题意描述 传送门 给你 \(N\) 段时间其中 \(B\) 段时间你要用来睡眠,再给你每个时间睡眠可获得的效用值 \(U_i\). 可惜的是你每 ...

  8. Cocos Creator 源码解读:引擎启动与主循环

    前言 预备 不知道你有没有想过,假如把游戏世界比作一辆汽车,那么这辆"汽车"是如何启动,又是如何持续运转的呢? 如题,本文的内容主要为 Cocos Creator 引擎的启动流程和 ...

  9. SQL service 数据插入

    目的:实现对数据库XDSA中表S72.C72.SC72的数据插入 1.构建数据库 2.构建表 3.插入数据 插入数据语句: ① 命令: INSERT INTO TableNameVALUES('值', ...

  10. input 与 button 的问题 (空隙/不等高/对不齐)及 解决办法

    1. input 与 button 为什么有空隙? - 要明白为什么,需要了解一下几点基础知识(耐心看完,你会发现竟如此简单)     1. input 与 button 都属于行级块元素,都具有文本 ...