聊聊 传统IO和网络IO
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的更多相关文章
- 多路复用 阻塞/非阻塞IO模型 网络IO两个阶段
1.网络IO的两个阶段 waitdata copydata send 先经历:copydata阶段 recv 先经历:waitdata阶段 再经历 copydata阶段 2.阻塞的IO模型 之前写的都 ...
- 磁盘 IO 和网络 IO 该如何评估、监控、性能定位和优化?
生产中经常遇到一些IO延时长导致的系统吞吐量下降.响应时间慢等问题,例如交换机故障.网线老化导致的丢包重传:存储阵列条带宽度不足.缓存不足.QoS限制.RAID级别设置不当等引起的IO延时. 一.评估 ...
- Socket-IO 系列(一)Linux 网络 IO 模型
Socket-IO 系列(一)Linux 网络 IO 模型 一.基本概念 在正式开始讲 Linux IO 模型前,先介绍 5 个基本概念. 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器, ...
- 阿里、腾讯热门面试题:聊聊Unix与Java的IO模型?(含详细解析)
众所周知 如果去百度.腾讯等一线大厂面试,一定会深入考候选人的基础技术功底,其中尤为关键和重视的就是IO相关的技术和知识. 而要搞明白IO相关的概念,首先就得弄清楚同步与异步,阻塞与非阻塞到底是什么意 ...
- 我对网络IO的理解
Unix/Linux系统下IO主要分为磁盘IO,网络IO,我今天主要说一下对网络IO的理解,网络IO主要是socket套接字的读(read).写(write),socket在Linux系统被抽象为流( ...
- 网络io控制器
网络io控制器 网络io控制器 ZLAN6842,ZLAN6844是8路远程网络IO控制器.含有8路DI.8路DO,8路AI输入.其中DI支持干节点和湿节点,带光耦隔离:DO为继电器输出,具有5A 2 ...
- 漫谈Java IO之普通IO流与BIO服务器
今天来复习一下基础IO,也就是最普通的IO. 网络IO的基本知识与概念 普通IO以及BIO服务器 NIO的使用与服务器Hello world Netty的使用与服务器Hello world 输入流与输 ...
- 并发编程 - IO模型 - 1.io模型/2.阻塞io/3.非阻塞io/4.多路复用io
1.io模型提交任务得方式: 同步:提交完任务,等结果,执行下一个任务 异步:提交完,接着执行,异步 + 回调 异步不等结果,提交完任务,任务执行完后,会自动触发回调函数同步不等于阻塞: 阻塞:遇到i ...
- 5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO
POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...
随机推荐
- win10系统安装robotframework环境时,不能成功安装autoItLibrary报错的问题解决
安装了autoit-v3-setup.exe,把autoItLibrary导入ride.py后仍然置红,开始DOS环境下手动安装autoLibrary,执行命令后如下报错:Running setup. ...
- SpringApplication.run(xxx.class, args)背后的东东——整体脉络
从spring到springmvc,再到springboot.springcloud,应用程序api开发调用方面都已经非常熟悉,但对spring背后的扩展机制:为何一个简单的main方法可以实现这么强 ...
- STM32入门系列-使用库函数点亮LED软硬件分析
电路图分析 首先找来单片机的原理图,根据原理图进行相关的设计工作. 例如在上图中相同网络标号表示它们是连接在一起的,因此D1发光二极管阴极是连接在STM32的PC0管脚上,D2指示灯阴极连接在PC1管 ...
- Centos7或RedHat7下安装Mysql
一次简单的Mysql安装记录 前言 由于网上安装Mysql的方式有很多种,但有些方式并未安装成功,比如用Yum源,还待后续查看具体是哪一步出了问题 以rpm包的形式安装Mysql 第一步:yum in ...
- LWJGL3的内存管理,第二篇,栈上分配
LWJGL3的内存管理,第二篇,栈上分配 简介 为了讨论LWJGL在内存分配方面的设计,本文将作为该系列随笔中的第二篇,用来讨论在栈上进行内存分配的策略,该策略在 LWJGL3 中体现为以 Memor ...
- Python - 生成 requirement.txt 文件
前言 Python项目中,一般都会有一个 requirements.txt 文件 这个文件主要是用于记录当前项目下的所有依赖包及其精确的版本号,以方便在一个新环境下更快的进行部署 如何生成 requi ...
- 5.MVCC
5 MVCC 全称是Multi-Version Concurrent Control,即多版本并发控制,在MVCC协议下,每个读操作会看到一个一致性的snapshot,并且可以实现非阻塞的读.MV ...
- 0 quickstart
说明 使用的安装包有: Prism 6.3 Unity 4.0.1 基于Prism框架的应用程序都包含一个主项目和若干功能模块,主项目负责启动时初始化工作,包括依赖注入容器,定义Shell等等.功能模 ...
- Python爬虫-换行的匹配
之前在学习爬虫的时候遇到了匹配内容时发现存在换行,这时没法匹配了,后来在网上找到了一种方法,当时懒得记录,今天突然有遇到了这种情况,想想还是在这里记录一下吧. 当时爬取的时csdn首页博客,如下图 看 ...
- Sentinel 的一些小扩展
随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制.熔断降级.系统自适应保护等多个维度来帮助您保障微服务的稳定 ...