IO 模型

传统 IO读写

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

  1. /**
  2. * 传统的IO读取
  3. * @param oriStr
  4. * @param destStr
  5. */
  6. public void customRead(String oriStr,String destStr){
  7. FileInputStream in = null;
  8. FileOutputStream os = null;
  9. try {
  10. in = new FileInputStream(oriStr);
  11. os = new FileOutputStream(destStr);
  12. //一次读取1K 数据
  13. byte[] bytes = new byte[1024];
  14. while(in.read(bytes)!=-1){
  15. os.write(bytes);
  16. }
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }finally {
  20. try {
  21. in.close();
  22. os.close();
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. }
  28.  
  29. /**
  30. * 带缓冲区的IO读取
  31. * @param oriStr
  32. * @param destStr
  33. */
  34. public void bufferRead(String oriStr,String destStr){
  35. BufferedInputStream in = null;
  36. BufferedOutputStream os = null;
  37. try {
  38. in = new BufferedInputStream(new FileInputStream(oriStr));
  39. os = new BufferedOutputStream(new FileOutputStream(destStr));
  40. //一次读取1K 数据
  41. byte[] bytes = new byte[1024];
  42. while(in.read(bytes)!=-1){
  43. os.write(bytes);
  44. }
  45. } catch (Exception e) {
  46. e.printStackTrace();
  47. }finally {
  48. try {
  49. in.close();
  50. os.close();
  51. } catch (IOException e) {
  52. e.printStackTrace();
  53. }
  54. }
  55. }

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[],是不是很熟悉,这个套路)就是应用缓存,负责在内存中保存读取的那一整块数据

  1. //伪代码
    public void nioRead() {
  2. FileChannel channel=null;
  3. try{
  4. RandomAccessFile raf=new RandomAccessFile("src/exp_io.txt","rw");
  5. //获取通道
  6. channel=raf.getChannel();
  7. if(0==raf.length()){
  8. return;
  9. }
  10. //分配缓存空间
  11. ByteBuffer buffer=ByteBuffer.allocate((int)raf.length());
  12. byte [] bytes=new byte[(int)raf.length()];
  13. //将数据写入缓存
  14. int bytesRead=channel.read(buffer);
  15. int i=0;
  16. while (bytesRead!=-1){
  17. buffer.flip();
  18. while (buffer.hasRemaining()){
  19. //从缓存读取数据
  20. bytes[i]=buffer.get();
  21. i++;
  22. }
  23. //将所有未读的数据拷贝到Buffer起始处。然后将position设到最后一个未读元素正后面
  24. //现在向缓存中写入数据时不会覆盖未读的数据
  25. buffer.compact();
  26. bytesRead=channel.read(buffer);
  27. }
  28. System.out.println(new String(bytes));
  29. }catch (Exception e){
  30.  
  31. }finally {
  32. try{
  33. if (channel!=null){
  34. channel.close();
  35. }
  36. }catch (Exception e){
  37.  
  38. }
  39. }
  40. }

  

总结

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. ATOM基础教程一使用前端插件emmet(16)

    emmet简介 http://blog.csdn.net/zsl10/article/details/51956791 emmet的前身是Zen coding,从事Web前端开发的工程师对该插件并不陌 ...

  2. 16 String类

    java中的所有的字符串文字(例如"abc","123")都可以看做是实现了此类的实例对象 eg: String str = new String(); str ...

  3. AT3557 Four Coloring

    题目链接 题解 先把每个格子看做一个点 (所谓的切比雪夫距离的转化) ,然后把这些点组成的矩形旋转45度,再把他塞到一个每个格子大小为\(d*d\)的网格图中,那么在一个格子上的点颜色相同 代码 #i ...

  4. STM32入门系列-STM32时钟系统,时钟使能配置函数

    之前的推文中说到,当使用一个外设时,必须先使能它的时钟.怎么通过库函数使能时钟呢?如需了解寄存器配置时钟,可以参考<STM32F10x中文参考手册>"复位和时钟控制(RCC)&q ...

  5. C语言经典100例-ex002

    系列文章<C语言经典100例>持续创作中,欢迎大家的关注和支持. 喜欢的同学记得点赞.转发.收藏哦- 后续C语言经典100例将会以pdf和代码的形式发放到公众号 欢迎关注:计算广告生态 即 ...

  6. python开发基础(一)-if条件判断,while循环,break,continue,

    条件语句 (1)if 基本语句 if 条件 : 内部代码块 else: .... print() (2)if 嵌套 (3)if elif 语句 (4)if 1==1: pass # if不执行,pas ...

  7. Java如何正确比较浮点数

    看下面这段代码,将 d1 和 d2 两个浮点数进行比较,输出的结果会是什么? double d1 = .1 * 3; double d2 = .3; System.out.println(d1 == ...

  8. 【Kata Daily 190927】Counting sheep...(数绵羊)

    题目: Consider an array of sheep where some sheep may be missing from their place. We need a function ...

  9. selenium-常用操作总结

    from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome ...

  10. 微服务接口设计(RESTful规范)

    微服务的接口设计(RESTful规范) 基本知识 URI:在RESTful架构中,每个URI代表一种资源 URI规范: 不用大写 用中杠-,不用下划线_ 路径中不能有动词,只能有名词 名词表示资源集合 ...