`
guibin
  • 浏览: 363654 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java NIO 入门(四)Buffer内部原理

    博客分类:
  • Java
阅读更多
Java NIO 入门(四)Buffer内部原理
guibin.beijing@gmail.com

概述
在这节中,我们将关注NIO的Buffer中两个重要的组件:状态变量和访问方法。
状态变量对于前面提到的“内部计数系统”而言相当重要,每次进行完读写之后,Buffer的状态都随之改变。通过记录和跟踪这些改变,Buffer才可以把Buffer内部的资源管理好。

当你从Channel中读数据时,数据首先放到了Buffer中。在某些情况下,你可以直接把这个Buffer写入另一个Channel中,但是通常情况下,你可能想看看数据内容,这个想法可以通过方法get()实现。相似的,当你想要把原始数据放进Buffer中,你可以使用put()方法。

在这节中,我们将学习NIO中的状态变量和访问方法。每个组件都会涉及到,并且有机会查看具体的使用。然而NIO的内部计数系统起初看起来可能有些复杂,你很快会看到内部计数系统实际上为你做了哪些事情。

状态变量
总共有三个值可以被用来表示在给定的任何时刻Buffer的状态,他们分别是:
  • position
  • limit
  • capacity

这三个变量跟踪了Buffer的状态和Buffer所包含的数据。
接下来我们将逐一检查每个细节,并且也看看为什么这样的设计适合典型的读/写(输入/输出)处理。比如仅仅这个例子,我们假设从一个Channel拷贝数据到另一个Channel。

Position
回忆一下,Buffer实际上也就是个array。当你从Channel中读数据时,你把从Channel中读出来的数据放进底层array,position变量用来跟踪截止目前为止已经写了多少数据。更精确的讲,它指示如果下次写Buffer时数据应该进入array的哪个位置。因此如果已经从Channel中读出了3个字节,Buffer的position会被置为3,指向array中第四个位置。
相似的,如果正在向Channel中写入数据,你需要从Buffer中获取要写的数据,此时position持续的跟踪你已经从Buffer中读取了多少数据。更精确的说,position指示了下一次从Buffer中读取数据时将读入array的哪个元素。因此如果你已经向Channel中写了5个byte,Buffer的position被置为5,指向array中第六个元素。

Limit
在从Buffer中向Channel中写数据时,limit变量指示了还剩多少数据可以读取,在从Channel中读取数据到Buffer中时,limit变量指示了还剩多少空间可供存放数据。
position正常情况下小于或者等于limit。

Capacity
Buffer的Capacity指示Buffer最多能够存储的数据。实际上,它指示了底层array的容量,或者至少是底层array允许使用的空间数量。
Limit永远不会大于capacity。

以实例来观察这三个变量
我们从一个新建的Buffer开始。由于是例子的缘故,我们假设Buffer有一个8字节大小的Capacity。此时Buffer的状态如下所示:


回忆之前所讲的,limit不会大于capacity,在这个例子中,limit和capacity都会被设为8。我们通过在array尾部用箭头指示的方式表示。


此时position设置为0。如果我们从Channel读了一些数据进入Buffer,下一个字节将会被存入位置为0的地方。如果我们从Buffer中写数据进入Channel,Buffer中下一个被读的字节将从位置0取得。position的设置如下图所示:



因为capacity一旦设置好就不会改变了,之后的讨论我们将暂时忽略capacity。

第一次读操作
现在我们准备好了在我们新建的Buffer上开始读/写操作了。我们开始从Channel中读一些数据进入Buffer,第一次读3个字节。读之前position为0,读完后position从0增长到3,如下所示:


第二次读操作
第二次读操作,我们将再读2个字节从Channel到Buffer中,这两个字节存储的位置从之前的position即3开始,读完后position增加了2变为5。如下图:



Flip操作
到目前位置,我们结束了从Channel中读的操作,现在开始将数据写入输出Channel中。在做写操作之前,我们必须调用一次flip()方法,这个方法做了两件重要的事情:
1. 将limit设置到当前的position处。
2. 设置position为0。
上幅图展示了在执行flip之前的Buffer,下面这幅图展示了执行了flip() 之后的Buffer:



现在我们已经准备好了把数据从Buffer中写到Channel中。Position已经设置为0,意思是说我们将获得的下一个字节为位置为0的字节,limit已经设置到了之前的position处,意思是此时Buffer中包含有之前读入Buffer中的所有字节。

第一次写操作
在我们第一次的写操作中,我们从Buffer中取出4个字节,然后写入output channel中。这个操作使得position从0增加到4,而limit没有变化,如下所示:



第二次写操作
目前为止,只剩一个字节可写了。当我们调用flip()时,limit被设置成5,并且position不能超越limit。因此最后的写操作从Buffer取出一个字节并写入output Channel中。这次写操作会将position增加到5,而limit不变。如下所示:



Clear操作
在我们的最后一步是调用Clear方法。这个方法会重置Buffer以准备接收新数据。Clear做了2件重要的事情:
1. 设置limit为0以匹配capacity。
2. 设置position为0。
下面的图展示了当调用完flip()之后的Buffer的状态:



一个能工作的Buffer
下面的代码总结了使用Buffer从一个Channel拷贝数据到另一个Channel
while(trie) {
  buffer.clear();
  int r = fcin.read( buffer );

  if (r==-1) {
    break;
  }

  buffer.flip();
  fcout.write( buffer );
}

read()和write()方法极大的简化了程序,由于Buffer处理了所有的细节。clear()和flip()方法用来切换Buffer的读和写。

本文参考自http://www.cs.brown.edu/courses/cs161/papers/j-nio-ltr.pdf

  • 大小: 23.6 KB
  • 大小: 37 KB
  • 大小: 29.9 KB
  • 大小: 31.6 KB
  • 大小: 31.8 KB
  • 大小: 26.9 KB
  • 大小: 27.8 KB
  • 大小: 27.8 KB
  • 大小: 33.2 KB
0
2
分享到:
评论

相关推荐

    java nio入门学习,两个pdf

    java nio入门学习,两个pdfjava nio入门学习,两个pdf

    java nio 入门

    java nio 入门,来自于IBM中文站

    JavaNIO chm帮助文档

    Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) FileChannel Java NIO系列教程(八) ...

    Java NIO的介绍及工作原理

    Java NIO的介绍及工作原理Java NIO的介绍及工作原理

    java NIO技巧及原理

    java NIO技巧及原理解析,java IO原理,NIO框架分析,性能比较

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    Java NIO入门的源码

    这是用于JAVA NIO入门教程的源码,直接看也能学到不少哦

    Java NIO实战开发多人聊天室

    12-Java NIO-Buffer-概述.mp4 13-Java NIO-Buffer-基本使用.mp4 14-Java NIO-Buffer-三个属性和类型.mp4 17-Java NIO-Buffer-缓冲区分片.mp4 18-Java NIO-Buffer-只读缓冲区.mp4 19-Java NIO-Buffer-直接缓冲区.mp4 ...

    Java NIO入门

    NIO 的创建目的是为了让 Java 程序员可以实现高速 I/O 而无需编写自定义的本机代码。NIO 将最耗时的 I/O 操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度。

    java nio中文版

    java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...

    java NIO入门(中英+代码)

    java NIO入门适合入门j

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    java nio 包读取超大数据文件

    Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据...

    Java NIO英文高清原版

    Java NIO英文高清原版

    NIO 入门.chm,NIO 入门.chm

    NIO入门.chm NIO入门.chm NIO入门.chm

    java NIO 中文版

    讲解了 JavaIO 与 JAVA NIO区别,JAVA NIO设计理念,以及JDK中java NIO中语法的使用

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    java NIO原理和使用

    java nio 附带例子 以及原理 java nio 附带例子 以及原理 java nio 附带例子 以及原理 java nio 附带例子 以及原理

    java nio 实现socket

    java nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socket

    Java NIO原理 图文分析及代码实现

    Java NIO原理 图文分析及代码实现

Global site tag (gtag.js) - Google Analytics