聊聊 传统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,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. ...
随机推荐
- Jenkins部署分支报Finished: UNSTABLE的问题解决
近期将代码分支部署到Jenkins上时报Finished: UNSTABLE,检查服务器无报错日志.怀疑是磁盘空间不足所致. 首先,在服务器上输入df -lh 查看本地磁盘使用情况,发现空间几乎被用完 ...
- PHP中双引号和单引号的区别
在PHP中,字符串数值有单引号和双引号两种. 区别: 单引号:系统不做复杂的转义.只转义\'和\\两种转义,其他的按原样输出. 双引号:则转义比较多,\",\\,\r,\t,\n,\$等. ...
- STM32入门系列-STM32时钟系统,自定义系统时钟
在时钟树的讲解中我们知道,通过修改PLLMUL中的倍系数值(2-16)可以改变系统的时钟频率.在库函数中也有对时钟倍频因子配置的函数,如下: void RCC_PLLConfig(uint32_t R ...
- 看完这篇 final、finally 和 finalize 和面试官扯皮就没问题了
我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star https://github.com/crisxuan/bestJavaer 已提交此篇文章 final 是 Java 中的关键字 ...
- PuTTY SSH 使用证书免密码登录
1.用PuTTY SSH 密钥生成工具puttygen.exe生成密钥.生成的密钥类型和位数按照默认的就OK,SSH-2 RSA,1024位生成密钥时你需要在空白区域移动鼠标,以便产生随机数据点击保存 ...
- 【转载】TCP/IP协议栈
TCP/IP 协议栈是一系列网络协议的总和,是构成网络通信的核心骨架,它定义了电子设备如何连入因特网,以及数据如何在它们之间进行传输.TCP/IP 协议采用4层结构,分别是应用层.传输层.网络层和链路 ...
- CEF避坑指南(一)——编译并自制浏览器
CEF即Chromium Embedded Framework,Chrome浏览器嵌入式框架.我们可以从自制浏览器入手,深入学习它.它提供了接口供程序员们把Chrome放到自己的程序中.许多大型公司, ...
- win10,安装 vmware 后没有虚拟网卡,导致虚拟机没有 ip
1.确认关闭windows firewall 服务,最保险的关闭时先把服务改为手动再关闭防止塔自动启动! 2.确认开启Device Install Service .Device Setup Ser ...
- 手把手教你使用Vuex(一)
1.定义 vuex 是一个专门为vue.js应用程序开发的状态管理模式. 这个状态我们可以理解为在data中的属性,需要共享给其他组件使用的部分.也就是说,是我们需要共享的data,使用vuex进行统 ...
- 一、智能指针及线程同步总结------linux多线程服务端编程
更新2.0 二.多线程及服务器编程总结------linux多线程服务端编程 https://www.cnblogs.com/l2017/p/11335609.html 三.分布式编程总结------ ...