`
春花秋月何时了
  • 浏览: 40008 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Java NIO Buffer缓冲区

阅读更多

缓冲区简介

操作系统有用户空间与系统空间的概念,JVM对应的JAVA进程是位于用户空间的,处于该空间的进程不能直接访问硬件设备,当JAVA进程要进行I/O操作时,只能通过系统调用将控制权交给内核,内核准备好进程所需要的数据,将这些数据拷贝到用户空间缓冲区(如下图所示)。

Java NIO中的Buffer用于和NIO通道进行交互。如你所知,数据是从通道读入缓冲区,从缓冲区写入到通道中的。

缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。

为了理解Buffer的工作原理,需要熟悉它的三个属性:

  • capacity
  • position
  • limit

position和limit的含义取决于Buffer处在读模式还是写模式。不管Buffer处在什么模式,capacity的含义总是一样的。

这里有一个关于capacity,position和limit在读写模式中的说明,详细的解释在插图后面。

capacity

作为一个内存块,Buffer有一个固定的大小值,也叫“capacity”.你只能往里写capacity个byte、long,char等类型。一旦Buffer满了,需要将其清空(通过读数据或者清除数据)才能继续写数据往里写数据。

position

当你写数据到Buffer中时,position表示当前的位置。初始的position值为0.当一个byte、long等数据写到Buffer后, position会向前移动到下一个可插入数据的Buffer单元。position最大可为capacity – 1.

当读取数据时,也是从某个特定位置读。当将Buffer从写模式切换到读模式,position会被重置为0. 当从Buffer的position处读取数据时,position向前移动到下一个可读的位置。

limit

在写模式下,Buffer的limit表示你最多能往Buffer里写多少数据。 写模式下,limit等于Buffer的capacity。

当切换Buffer到读模式时, limit表示你最多能读到多少数据。因此,当切换Buffer到读模式时,limit会被设置成写模式下的position值。换句话说,你能读到之前写入的所有数据(limit被设置成已写数据的数量,这个值在写模式下就是position)

Buffer方法

flip():将Buffer读模式切换到写模式,并且将position制为0,并将limit设置成之前position的值.

clear():清空整个缓冲区,position将被设回0,limit被设置成 capacity的值.Buffer中的数据并未清除.如果Buffer中有一些未读的数据,调用clear()方法,数据将“被遗忘”,意味着不再有任何标记会告诉你哪些数据被读过,哪些还没有。

compact():只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面, 将position设到最后一个未读元素正后面。limit属性依然像clear()方法一样,设置成capacity。现在Buffer准备好写数据了,但是不会覆盖未读的数据。

allocate(1024):初始化Buffer,设定的值就决定capacity值的大小

rewind():将position设回0,所以你可以重读Buffer中的所有数据。limit保持不变,仍然表示能从Buffer中读取多少个元素(byte、char等)

mark()与reset():通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position

 

equals():当满足下面三个条件时,两个Buffer才是相等

  • 有相同的类型(byte、char、int等)
  • Buffer中剩余的byte、char等的个数相等
  • Buffer中所有剩余的byte、char等都相同

只比较的是剩余的数据

compareTo():满足下列条件,则认为一个Buffer“小于”另一个Buffer

  • 第一个不相等的元素小于另一个Buffer中对应的元素
  • 所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)

注意点:

  1. ByteBuffer byteBuffer = ByteBuffer.allocate(1);在从通道往buffer中读入之后,使用byteBuffer.get()获取的时候,不可重复调用,因为get()方法会移动position,使得多次调用get()方法获取的内容是不同的

  2. ByteBuffer中,put(int index, byte b)方法不会移动position,但是put(byte b)会移动position

  3. ByteBuffer.allocate(int capacity)ByteBuffer.allocateDirect(int capacity)的区别:使用allocate来创建缓冲区,并不是一下子就分配给缓冲区capacity大小的空间,而是根据缓冲区中存储数据的情况来动态分配缓冲区的大小(实际上,在底层Java采用了数据结构中的堆来管理缓冲区的大小),因此,这个capacity可以是一个很大的值,如1024*1024(1M)。使用allocateDirect(由操作系统分配,脱离了JVM)方法可以一次性分配capacity大小的连续字节空间。通过allocateDirect方法来创建具有连续空间的ByteBuffer对象虽然可以在一定程度上提高效率,但这种方式并不是平台独立的。也就是说,在一些操作系统平台上使用allocateDirect方法来创建ByteBuffer对象会使效率大幅度提高,而在另一些操作系统平台上,性能会表现得非常差。而且allocateDirect方法需要较长的时间来分配内存空间,在释放空间时也较慢。因此,在使用allocateDirect方法时应谨慎

参考链接:

http://www.jianshu.com/p/052035037297

分享到:
评论

相关推荐

    Java NIO实战开发多人聊天室

    01-Java NIO-课程简介....17-Java NIO-Buffer-缓冲区分片.mp4 18-Java NIO-Buffer-只读缓冲区.mp4 19-Java NIO-Buffer-直接缓冲区.mp4 21-Java NIO-Selector-概述.mp4 23-Java NIO-Selector-示例代码(客户端).mp4 24

    java NIO 视频教程

    标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。 Java NIO: Non-blocking IO(非阻塞IO) Java NIO...

    Java NIO Buffer过程详解

    主要介绍了Java NIO Buffer过程详解,缓冲区在java nio中负责数据的存储。缓冲区就是数组。用于存储不同数据类型的数据。,需要的朋友可以参考下

    java nio教程pdf

    标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。 Java NIO: Asynchronous IO(异步IO) Java NIO可以...

    Java NIO(通道+缓冲区+选择器)

    Java NIO通道:通道基础、文件通道、Socket通道、工具类 Java NIO缓冲区:基础、缓冲区(Buffer)、创建缓冲区、直接缓冲区(DirectByteBuffer) Java NIO选择器:核心概念、选择器使用、Demo、选择器深入、

    详细了解JAVA NIO之Buffer(缓冲区)

    主要介绍了JAVA NIO之Buffer(缓冲区)的相关资料,文中讲解非常细致,帮助大家更好的学习JAVA NIO,感兴趣的朋友可以了解下

    尚硅谷Java视频_NIO 视频教程

    尚硅谷_NIO_缓冲区(Buffer)的数据存取 ·03. 尚硅谷_NIO_直接缓冲区与非直接缓冲区 ·04. 尚硅谷_NIO_通道(Channel)的原理与获取 ·05. 尚硅谷_NIO_通道的数据传输与内存映射文件 ·06. 尚硅谷_NIO_分散读取与聚集...

    Java NIO缓冲

    缓冲区(buffer)是从即将写入通道(channel)或刚刚从通道中读出的一段数据。它是一个持有数据,并扮演NIO通道端点的对象。缓冲区为数据访问和读写过程提供正式机制。  它是NIO和老版Java I/O的一个主要区别。...

    java8源码-nio:java8nio使用的总结

    NIO_缓冲区(Buffer)的数据存取 缓冲区(Buffer):在 Java NIO 中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据 4. NIO_直接缓冲区与非直接缓冲区 非直接缓冲区:通过 allocate() 方法分配缓冲区,将...

    javasnmp源码-nio-learn:JavaNIO使用示例,NIO的使用,TCP,UDP的简单示例

    Buffer是数据的容器,在nio中负责数据的存取,java为不同数据类型提供了相对应的缓冲区类型 如:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer 、DoubleBuffer 等。 Buffer的基本使用 ...

    java8中NIO缓冲区(Buffer)的数据存储详解

    在本篇文章中小编给大家分享了关于java8中NIO缓冲区(Buffer)的数据存储的相关知识点,需要的朋友们参考下。

    Java NIO 网络编程初探

    NIO支持面向缓冲区的、基于通道的IO操作。能够更加高效的进行IO操作。NIO同样拥有文件读写,网络通信等IO操作,今天我们来看看NIO中的TCP网络通信的使用方法。 2. Java NIO 三大核心 Java NIO 有三大核心要素:...

    2021最新-Java NIO视频教程-视频教程网盘链接提取码下载 .txt

    教程内容涵盖:阻塞和非阻塞IO、Channel通道、Buffer缓冲区、Selector选择器、Pipe管道、FileLock文件锁,以及Path、Files、异步FileChannel和Charset字符编码等,并通过一个多人聊天室的综合案例,把所有的NIO知识...

    24 尚硅谷Java NIO视频

    教程视频:NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中

    [ Java ] 最通俗易懂的 Java NIO 讲解

    文章目录IO 与 NIO 的比较通道和缓冲区缓冲区(buffer)通道(channel)使用 NIO 完成本地通信使用 NIO 完成网络通信管道 IO 与 NIO 的比较 IO NIO 面向流(Stream Oriented) 面向缓冲区(Buffer Oriented)...

    Java流NIO

    什么是NIO Java NIO(NEW IO)是从Java1.4开始引入的新版IO,用来替代标准的Java IO API ...面向缓冲区(Buffer Oriented) 阻塞IO(Block IO) 无阻塞IO(Non Block IO) 无 Selectors(选择器)

    JAVA IO-NIO 详解

    NIO的核心组件包括Channel(通道)、Buffer(缓冲区)和Selector(选择器)。Channel是数据传输的通道,它替代了传统IO中的流;Buffer是数据的容器,它可以在Channel和程序之间进行数据的读写操作;Selector则用于...

    nio:Clojure对java.nio的支持

    定义新的强制功能缓冲区,字节缓冲区,字符缓冲区,双缓冲区,浮点缓冲区,整数缓冲区,长缓冲区,短缓冲区,通道,可读通道和可写通道。 这些功能已为您期望的许多类实现。 还定义了函数mmap来对文件进行内存映射...

    Java IO 体系.md

    - 缓冲区(Buffer) - 通道(Channel) - 示例:文件拷贝案例 - BIO 和 NIO 拷贝文件的区别 - 操作系统的零拷贝 - 选择器(Selectors) - 选择键(SelectionKey) - 示例:简易的客户端服务器通信 - 总结 ...

    Java面试高频知识点总结

    传统 IO 基于字节流和字符流进行操作,而 NIO 基于 Channel 和 Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据...

Global site tag (gtag.js) - Google Analytics