`
guibin
  • 浏览: 366557 次
  • 性别: 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 入门

    Java NIO(New Input/Output)是Java标准库中的一部分,自Java...通过理解并熟练掌握NIO的原理和使用,可以显著提升Java应用的性能和可扩展性。在实际项目中,可以根据需求选择合适的I/O模型,充分利用Java NIO的优势。

    java nio入门学习,两个pdf

    四、Java NIO的实际应用 1. **高并发服务器**:NIO在开发高性能、大并发的服务器时非常有用,例如聊天服务器、游戏服务器等。 2. **文件操作**:NIO提供了高效、灵活的文件读写能力,特别是对于大数据处理,如日志...

    Java NIO入门

    IBM的NIO入门教程通常会涵盖这些基础概念,并通过实例演示如何使用NIO进行实际的I/O操作。教程可能还会深入讲解NIO的高级特性,如scatter/gather(分散/聚集)读写,以及如何使用`Selector`进行多路复用。通过学习这...

    Java NIO入门的源码

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种I/O模型,旨在提供一种更高效、更具控制力的I/O操作方式。与传统的-blocking I/O(阻塞I/O)相比,NIO的关键在于它...

    NIO 入门.chm,NIO 入门.chm

    **NIO(New Input/Output)是Java编程语言中用于替代标准I/O(BIO,Blocking I/O)的一组API,它提供了非阻塞式的I/O操作方式,极大地提升了Java在处理I/O密集型应用时的性能。NIO在Java 1.4版本中被引入,之后在...

    IBM Java文档库 NIO 入门

    《IBM Java文档库 NIO 入门》这篇教程主要针对的是Java 1.4引入的New Input/Output (NIO)库,这是一个重要的更新,旨在提高Java程序的I/O性能,特别是面向块的I/O操作。NIO弥补了传统I/O(基于java.io.*包)的不足,...

    java NIO入门(中英+代码)

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种I/O模型,旨在提供一种更高效、更具控制力的I/O操作方式。与传统的 Blocking I/O(同步阻塞I/O)相比,NIO的核心特点...

    java_NIO_入门

    本教程旨在为读者提供一个全面的NIO入门指南,不仅涵盖了NIO的基础理论知识,还包括了实际编程中使用到的代码示例。 在学习NIO之前,读者需要掌握Java语言的一些基本概念,包括类、继承、包等。此外,如果读者对...

    NIO入门pdf分享

    《NIO入门》一书是理解Java NIO(New Input/Output)的重要参考资料,NIO在Java编程中扮演着至关重要的角色,特别是在处理高并发、大数据传输等场景下。本PDF文档将引领读者深入理解这一核心概念。 NIO,全称New ...

    nio入门 IBM教材,pdf格式

    ### NIO 入门知识点详解 #### 一、NIO 的引入及其背景 - **NIO 的起源**:NIO(New Input/Output)库是在 JDK 1.4 中引入的,旨在解决传统 Java I/O 操作的局限性和性能瓶颈。 - **改进目标**:NIO 通过提供高速...

    nio入门文档及示例代码

    本入门文档及示例代码旨在帮助开发者快速理解并掌握Java NIO的基本概念和用法。 一、NIO基础概念 1. **通道(Channels)**:NIO的核心组件之一,它是连接到数据源(如文件、套接字)的通道,可以读写数据。常见的...

    java_NIO_入门(良好排版格式).pdf

    ### Java NIO 入门详解 #### 一、NIO 的背景与意义 **NIO (New Input/Output)** 是 Java 在 JDK 1.4 中引入的一个全新的输入输出库,旨在改进原有的 IO 库(主要位于 `java.io.*` 包中)的性能和功能。传统的 Java...

    Java springboot 整合mina 框架,nio通讯基础教程,mina框架基础教程.zip

    总结来说,本教程将引导你从理论到实践,掌握Java NIO的基本原理,理解Mina框架的使用,以及如何在SpringBoot环境中整合Mina实现高效的网络通信。通过这些知识的学习,你将具备开发高并发、高性能网络应用的能力。

    NIO入门

    **NIO(Non-blocking I/O)入门** 在Java编程领域,NIO(Non-blocking Input/Output,非阻塞I/O)是一种重要的I/O模型,它与传统的BIO(Blocking I/O)模型相比,提供了更高的并发性能和更有效的资源利用。NIO在...

    java入门学习源码

    源码可能涉及FileInputStream、FileOutputStream、BufferedReader、BufferedWriter等的使用,以及Channel、Selector和Buffer的NIO操作。 通过分析"Java入门学习源码"中的JavaProject,初学者可以逐步掌握上述知识点...

Global site tag (gtag.js) - Google Analytics