• Java NIO -2


    NIO

    http://www.cnblogs.com/puyangsky/p/5840873.html

    --

    操作系统与 Java 基于流的 I/O模型有些不匹配。操作系统要移动的是大块数据(缓冲区),这往往是在硬件直接存储器存取( DMA)的协助下完成的。而 JVM 的 I/O 类喜欢操作小块数据——单个字节、几行文本。结果,操作系统送来整缓冲区的数据, java.io 的流数据类再花大量时间把它们拆成小块,往往拷贝一个小块就要往返于几层对象。操作系统喜欢整卡车地运来数据, java.io 类则喜欢一铲子一铲子地加工数据。有了 NIO,就可以轻松地把一卡车数据备份到您能直接使用的地方( ByteBuffer 对象)。但是Java里的RandomAccessFile类是比较接近操作系统的方式。

    Java NIO主要依赖的组件有三个:缓冲区Buffer、通道Channel和选择器Selector。

    2.1 缓冲区(Buffer)

    Buffer家族主要有这么些个成员,根据类名也大概能猜到它们的用处,用的最多的是ByteBuffer,在下面的例子中也会主要用到它。

    2.1.1 缓冲区属性

    容量(capacity):缓冲区的最大大小

    上界(limit):缓冲区当前的大小

    位置(position):下一个要读写的位置,由get()和put()更新

    标记(mark):备忘位置,由mark()来指定mark = position,由reset()来指定position=mark

    它们之间的大小关系:

    0 <= mark <= position <= limit <= capacity

    Buffer/ ByteBuffer 源代码

    public final int remaining()
    {
    return this.limit - this.position;
    }

    public final boolean hasRemaining()
    {
    return this.position < this.limit;
    }

    public final Buffer flip()
    {
    this.limit = this.position;
    this.position = 0;
    this.mark = -1;
    return this;
    }

    public final Buffer clear()
    {
    this.position = 0;
    this.limit = this.capacity;
    this.mark = -1;
    return this;
    }

    2.2 通道(Channel)

    开始我不是很理解Channel这个东西为什么要存在,看了书才慢慢明白,缓冲区为我们装载了数据,但是数据的写入和读取并不能直接进行read()和write()这样的系统调用,而是JVM为我们提供了一层对系统调用的封装。而Channel可以用最小的开销来访问操作系统本身的IO服务,这就是为什么要有Channel的原因。

    2.2.2.1 打开

    FileChannel只能通过工厂方法来实例化,那就是调用RandomAccessFile、FileInputStream和FileOutputStream的getChannel()方法。如:

    RandomAccessFile file = new RandomAccessFile("a.txt", "r");
    FileChannel fc = file.getChannel();

     
    读取文件的整个过程相比原生的I/O方法还是略显麻烦,但是我们如果把数据看成一堆煤矿,把ByteBuffer看成装煤的矿车,而FileChannel看成是运煤的矿道,那么上面的过程就演变成了:先打通一条矿道,然后把煤矿装在小车里运出来。形象的记忆更利于理解这个过程。

     同样考虑一下形象化的过程:我们首先把煤矿装入小车(buffer.put()),并打开一条通往矿山的矿道(FileOutputStream.getChannel()),接着把煤矿运输进去(FileChannel.write(buffer))。还是很容易理解的吧

  • 相关阅读:
    rails采用MongoDB感觉相当不错!
    LWC: 将VF页面显示在LWC中
    Salesforce: System.TypeException: Invalid integer: 2185340704
    Salesforce: Report没有权限访问
    Maven Archetype 多 Module 自定义代码脚手架
    2021年度总结
    [转摘]Lucene学习总结之一:全文检索的基本原理
    DataTable.Rows.Remove(row) 与 DataTable.Rows[i].Delete()区别
    Lucene.net根据Sort走到了不同的类处理
    调用腾讯QQ天气预报的JS代码
  • 原文地址:https://www.cnblogs.com/kakaisgood/p/6651471.html
Copyright © 2020-2023  润新知