`
xiaoming2xiaohong
  • 浏览: 41350 次
社区版块
存档分类
最新评论

Java NIO ByteBuffer

阅读更多

    <span class="Apple-style-span" style="font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 26px; text-align: left; text-indent: 0px; white-space: normal; background-color: #ffffff; font-family: Arial; color: #333333;">
</span>


在 NIO 库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问 NIO 中的数据,都是将它放到缓冲区中。缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不仅仅
是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。

buffer其实只是一个美化了的<span style="font-family: mceinline;">数组</span>


<h1 style="margin: 0px; padding: 0px;">
<span style="font-family: mceinline;">状态变量</span>
</h1>
跟踪数据的状态情况使buffer可以自己管理数据资源

<div>
position
: 其实是指从buffer读取或写入buffer的下一个元素位置。比如,已经写入buffer 3个元素那那么position就是指向第4个位置,即position设置为3(数组从0开始计)。
<div>
limit
:还有多少数据需要从buffer中取出,或还有多少空间可以放入。postition总是<=limit。
<div>
capacity
: 表示buffer本身底层数组的容量。limit绝不能>capacity。
<div>
filp():<span style="font-weight: normal;">作了两件事情:[b]<span style="font-weight: normal;">1.将limit指向现在position的位置 2.将position设置为0 (limit=position;position=0)</span>

</span>
[/b]

<div>??<span style="white-space: pre;"> </span>
????这个过程可以使之前buffer写入数据时改变的状态变为可以“准备读取”。因为之前写到buffer中的数据就是position 到 limit-1 两个位置之间(limit指向最后一个数据的后一个位置)。
<div><img style="border-style: none;" src="http://hi.csdn.net/attachment/201002/14/1772742_1266136803H88h.jpg" alt="filp" width="468" height="211">
<div>
clear():

<div>???<span style="white-space: pre;"> </span>
也作了两件事:1. limit=capacity 2.position=0
<div>这个过程可以使buffer读取数据时改变的状态改变为“清空并准备写入”。
<div><img style="border-style: none;" src="http://hi.csdn.net/attachment/201002/14/1772742_1266136802WB4z.jpg" alt="clear" width="468" height="246">
<h1 style="margin: 0px; padding: 0px;">访问方法</h1>
<div>以下都以bytebuffer为例
<div>get():
<div>???前三个get方法是相对读取。就是相对于位置状态来读取数据,并且会改变position位置状态。
<div>???byte get();
<div>???ByteBuffer get(byte dst[]);//读取bytebuffer中数据写入 dst[]
<div>???ByteBuffer get(byte dst[],int offset, int length);
<div>???
<div>???该读取数据是绝对读取(一个byte),即会忽略limit和position值。并完全绕过了缓冲区的状态统计方法。
<div>???就是说不会改变buffer内部的位置状态。
<div>???byte get(int index);
<div>?
<div>put();
<div>???与get类似 前四个put方法是相对读取。即受position 以及limit影响,并且会改变 position。
<div>???ByteBuffer put( byte b );
<div>???ByteBuffer put( byte src[] ); //从src[]写入bytebuffer
<div>???ByteBuffer put( byte src[], int offset, int length );
<div>???ByteBuffer put( ByteBuffer src );
<div>???最后一个是绝对写入 不会影响position等位置状态。
<div>???ByteBuffer put( int index, byte b );
<div>?
<div>除了byte的读写还有其他类型的读写方法。并且他们都存在相对以及绝
对两类。
<div>?
<div>操作的典型使用:
<div><br>
<div>while (true) {<br>
???? buffer.clear(); // 准备将数据写入buffer<br>
???? int r = fcin.read( buffer ); // channel读取外部系统的数据并写入 buffer<br>
???? if (r==-1) {<br>
?????? break;<br>
???? }<br>
???? buffer.flip(); //准备将数据读出buffer<br>
???? fcout.write( buffer ); // channel读取buffer的数据并写到相应的外部系统<br>
}
<div><br>
<h1 style="margin: 0px; padding: 0px;">高级应用</h1>
<h2 style="margin: 0px; padding: 0px;">
<span style="font-family: monospace;">缓存区的分配和包装</span>
</h2>
<div>
<div>
<span style="font-family: monospace;">ByteBuffer.allocate(int);方法可以分配(创建)一个byte类型的buffer。</span>

<div>
<span style="font-family: monospace;">ByteBuffer.wrap(byte[]);方法可以将一个已有的byte数组包装出一个新的bytebuffer对象。</span>

<div>
<span style="font-family: monospace;">后一种方式需要小心处理原来的那个byte数组。因为它可以直接访问了。</span>

<h2 style="margin: 0px; padding: 0px;">
<span style="font-family: monospace;">缓冲区的分片</span>
</h2>
<div>
<span style="font-family: monospace;">分片就是建立“子缓冲区”。子缓冲区共享父缓冲区的一部分底层数组位置。</span>

<div>
<span style="font-family: monospace;">在某种意义上,子缓冲区就像原来的缓冲区中的一个窗口。</span>

<div>
<span style="font-family: monospace;">这样当改变子缓冲区的内容时,父缓冲区的相应位置也会被改变。</span>

<div>
<span style="font-family: monospace;">分片操作是根据当前position以及limit的值来确定的。</span>

<div>
<span style="font-family: monospace;">buffer.position( 3 );</span>

<div>
<span style="font-family: monospace;">buffer.limit( 7 );</span>

<div>
<span style="font-family: monospace;">ByteBuffer slice = buffer.slice();</span>


<h2 style="margin: 0px; padding: 0px;">
<span style="font-family: monospace;">只读缓冲区</span>
</h2>
<div>
<span style="font-family: monospace;">asReadOnlyBuffer()方法可以返回一个与原buffer对象一样的对象,只是新的buffer对象是只读的。</span>

<h2 style="margin: 0px; padding: 0px;">
<span style="font-family: monospace;">直接缓冲区</span>

</h2>
<div>
<span style="font-family: monospace;">sun的定义:给定一个直接字节缓冲区,Java 虚拟机将尽最大努力直接对它执行本机 I/O 操作。也就是说,它会在每一次调用底层操作系统的本机 I/O 操作之前(或之后),尝试避免将缓冲区的内容拷贝到一个中间缓冲区中(或者从一个中间缓冲区中拷贝数据)。</span>

<div>
<span style="font-family: monospace;">创建directbuffer的方式是用ByteBuffer.allocateDirect( int )
;方法替代ByteBuffer.allocate(int);</span>

<h2 style="margin: 0px; padding: 0px;">
<span style="font-family: monospace;">内存影射文件I/O</span>
</h2>
<div>
<span style="font-family: monospace;">它读写要比其他IO快很多.</span>

<div>
<span style="font-family: monospace;">他使文件或文件的一部分由内存影射。但是只有操作该部分位置的数据才是以内存方式读写的,而不是整个文件读入内存。(并且他是一个os的底层机制。由os底层异步完成内存与物理磁盘上的数据同步)</span>

<div>
<span style="font-family: monospace;">影射文件可以通过FileChannel对象的map方法得到。</span>

<div>
<span style="font-family: monospace;">比如以下就是将一个文件的前1024个字节影射到内存,并创建一个MappedByteBuffer对象返回出来。MappedByteBuffer是ByteBuffer的一个子类。</span>

<div>
<span style="font-family: monospace;">MappedByteBuffer mbb = fc.map( FileChannel.MapMode.READ_WRITE, start, size );</span>

?

 
0
0
分享到:
评论
1 楼 Simon.C 2012-02-03  
清了那些多余的HTML标签吧……

相关推荐

    深入理解Apache Mina (6)---- Java Nio ByteBuffer与Mina ByteBuffer的区别

    本篇将深入探讨Java NIO(非阻塞I/O)中的ByteBuffer和Mina库自定义的ByteBuffer之间的区别。 Java NIO的ByteBuffer是Java标准库提供的一个核心类,它是通道(Channel)和缓冲区(Buffer)之间数据传输的主要媒介。它...

    Java NIO学习笔记——ByteBuffer用法

    本文主要关注的是Java NIO中的ByteBuffer,一个关键的数据容器,用于在通道(Channel)和缓冲区(Buffer)之间传输数据。ByteBuffer的用法是Java NIO学习中的核心内容。 首先,我们了解下ByteBuffer的基本概念。...

    java NIO.zip

    Java NIO提供了诸如ByteBuffer、CharBuffer、IntBuffer等类型,对应于不同的数据类型。缓冲区具有读写位置,可以通过flip()、clear()和rewind()等方法来管理缓冲区的状态,从而高效地进行数据读写。 3. **选择器...

    JAVA NIO 按行读取大文件支持 GB级别-修正版

    设计思想: 每次通过nio读取字节到 fbb中 然后对fbb自己中的内容进行行判断即 10 回车 13 行号 0 文件结束 这样字节的判断,然后 返回行 如果 到达 fbb的结尾 还没有结束,就再通过nio读取一段字节,继续处理。 ...

    java nio 读文件

    import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; public class FeiNioRead { public static void main(String[] args...

    java nio入门学习,两个pdf

    Java NIO定义了多个Buffer类,如ByteBuffer、CharBuffer、IntBuffer等,每个Buffer都有容量、位置、限制等属性,可以进行读写操作。 3. **选择器(Selectors)**:选择器用于监控多个通道的状态,当某个通道准备就绪...

    Java NIO Socket基本

    缓冲区类型包括ByteBuffer、CharBuffer、IntBuffer、DoubleBuffer等,它们都继承自`java.nio.Buffer`。 3. **选择器(Selector)**:用于监听多个通道的事件(如连接就绪、数据到达等),当某个通道准备好进行读写...

    java NIO详细教程

    ### Java NIO 详细教程知识点解析 #### 一、Java NIO 概述 Java NIO(New IO)是Java平台提供的一种新的IO操作模式,它首次出现在Java 1.4版本中,并在后续版本中不断完善。Java NIO 的设计目的是为了克服传统Java ...

    java nio 实现socket

    ### Java NIO 实现Socket通信详解 #### 一、NIO与传统IO的区别及优势 在探讨如何使用Java NIO实现Socket通信之前,我们需要先理解NIO(Non-blocking I/O,非阻塞I/O)与传统阻塞I/O之间的区别。 **传统阻塞I/O...

    Java.NIO资源下载资源下载

    根据提供的文件信息,我们可以提取并总结出关于Java NIO(New Input/Output)的重要知识点。 ### Java NIO 概述 Java NIO 是 Java 平台的一个重要特性,首次出现在 Java 1.4 版本中。它为 Java 开发者提供了一套...

    基于java NIO的socket通信demo

    对于Java NIO,我们通常使用`ByteBuffer`来存储和传输数据,它的`asCharBuffer()`方法可以方便地进行字符集转换。 字符集乱码问题在Java NIO中可以通过设置合适的字符集来解决。在读写数据时,我们需要明确指定字符...

    Java NIO 中英文版

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java平台中用于替代标准的I/O模型的一种新机制。在传统的Java I/O中,使用的是Blocking I/O,即阻塞式I/O,这种模型下,线程在等待数据就绪时会被...

    JavaNIO.pdf

    Java NIO中提供了多种类型的缓冲区,如ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer、MappedByteBuffer等,每种类型的缓冲区都有其特定的用途和应用场景。 通道...

    深入理解Apache_Mina

    Java NIO ByteBuffer是Java NIO中的一个核心组件,用于在通道中读写数据。而MinaByteBuffer则是在Mina框架中对ByteBuffer的进一步封装和抽象,它针对网络通信的特殊需求进行了优化。 在实际开发中,开发者会发现...

    nio.rar_FastCopyFile.java_NIO_UseFloatBuffer.java_java nio_文件锁

    Java NIO(New Input/Output)是Java标准库中提供的一种I/O模型,与传统的BIO( Blocking I/O)相比,NIO具有更好的性能和更高的灵活性。NIO的核心组件包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。...

    NIO(byteBuffer)按行读取文件

    使用nio byteBuffer 实现按行读取文件(大文件) 在window/linux/macOS上均测试通过 对于中文乱码也已处理成功 完整注释,可随需求更改 有问题请邮件:mly610865580@126.com

Global site tag (gtag.js) - Google Analytics