`
buaixianchen
  • 浏览: 24105 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java NIO 学习笔记 - ByteBuffer (转)

阅读更多

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

buffer其实只是一个美化了的数组。

状态变量
跟踪数据的状态情况使buffer可以自己管理数据资源

position: 其实是指从buffer读取或写入buffer的下一个元素位置。比如,已经写入buffer 3个元素那那么position就是指向第4个位置,即position设置为3(数组从0开始计)。
limit:还有多少数据需要从buffer中取出,或还有多少空间可以放入。postition总是<=limit。
capacity: 表示buffer本身底层数组的容量。limit绝不能>capacity。
filp():作了两件事情:1.将limit指向现在position的位置 2.将position设置为0 (limit=position;position=0)
       这个过程可以使之前buffer写入数据时改变的状态变为可以“准备读取”。因为之前写到buffer中的数据就是position 到 limit-1 两个位置之间(limit指向最后一个数据的后一个位置)。

clear():
    也作了两件事:1. limit=capacity 2.position=0
这个过程可以使buffer读取数据时改变的状态改变为“清空并准备写入”。

访问方法
以下都以bytebuffer为例
get():
   前三个get方法是相对读取。就是相对于位置状态来读取数据,并且会改变position位置状态。
   byte get();
   ByteBuffer get(byte dst[]);//读取bytebuffer中数据写入 dst[]
   ByteBuffer get(byte dst[],int offset, int length);
  
   该读取数据是绝对读取(一个byte),即会忽略limit和position值。并完全绕过了缓冲区的状态统计方法。
   就是说不会改变buffer内部的位置状态。
   byte get(int index);
 
put();
   与get类似 前四个put方法是相对读取。即受position 以及limit影响,并且会改变 position。
   ByteBuffer put( byte b );
   ByteBuffer put( byte src[] ); //从src[]写入bytebuffer
   ByteBuffer put( byte src[], int offset, int length );
   ByteBuffer put( ByteBuffer src );
   最后一个是绝对写入 不会影响position等位置状态。
   ByteBuffer put( int index, byte b );
 
除了byte的读写还有其他类型的读写方法。并且他们都存在相对以及绝对两类。
 
操作的典型使用:
view plaincopy to clipboardprint?
while (true) {  
     buffer.clear(); // 准备将数据写入buffer  
     int r = fcin.read( buffer ); // channel读取外部系统的数据并写入 buffer  
     if (r==-1) {  
       break;  
     }  
     buffer.flip(); //准备将数据读出buffer  
     fcout.write( buffer ); // channel读取buffer的数据并写到相应的外部系统  

while (true) {
     buffer.clear(); // 准备将数据写入buffer
     int r = fcin.read( buffer ); // channel读取外部系统的数据并写入 buffer
     if (r==-1) {
       break;
     }
     buffer.flip(); //准备将数据读出buffer
     fcout.write( buffer ); // channel读取buffer的数据并写到相应的外部系统
}
高级应用
缓存区的分配和包装
ByteBuffer.allocate(int);方法可以分配(创建)一个byte类型的buffer。
ByteBuffer.wrap(byte[]);方法可以将一个已有的byte数组包装出一个新的bytebuffer对象。
后一种方式需要小心处理原来的那个byte数组。因为它可以直接访问了。
缓冲区的分片
分片就是建立“子缓冲区”。子缓冲区共享父缓冲区的一部分底层数组位置。
在某种意义上,子缓冲区就像原来的缓冲区中的一个窗口。
这样当改变子缓冲区的内容时,父缓冲区的相应位置也会被改变。
分片操作是根据当前position以及limit的值来确定的。
buffer.position( 3 );
buffer.limit( 7 );
ByteBuffer slice = buffer.slice();
只读缓冲区
asReadOnlyBuffer()方法可以返回一个与原buffer对象一样的对象,只是新的buffer对象是只读的。
直接缓冲区
sun的定义:给定一个直接字节缓冲区,Java 虚拟机将尽最大努力直接对它执行本机 I/O 操作。也就是说,它会在每一次调用底层操作系统的本机 I/O 操作之前(或之后),尝试避免将缓冲区的内容拷贝到一个中间缓冲区中(或者从一个中间缓冲区中拷贝数据)。
创建directbuffer的方式是用ByteBuffer.allocateDirect( int );方法替代ByteBuffer.allocate(int);
内存影射文件I/O
它读写要比其他IO快很多.
他使文件或文件的一部分由内存影射。但是只有操作该部分位置的数据才是以内存方式读写的,而不是整个文件读入内存。(并且他是一个os的底层机制。由os底层异步完成内存与物理磁盘上的数据同步)
影射文件可以通过FileChannel对象的map方法得到。
比如以下就是将一个文件的前1024个字节影射到内存,并创建一个MappedByteBuffer对象返回出来。MappedByteBuffer是ByteBuffer的一个子类。
MappedByteBuffer mbb = fc.map( FileChannel.MapMode.READ_WRITE, start, size );


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wfeng007/archive/2010/02/14/5308614.aspx

分享到:
评论

相关推荐

    Java NIO学习笔记——ByteBuffer用法

    ByteBuffer的用法是Java NIO学习中的核心内容。 首先,我们了解下ByteBuffer的基本概念。ByteBuffer是一个字节缓冲区,可以存储字节序列。在NIO中,所有的数据读写都通过缓冲区进行,ByteBuffer与其他类型的Buffer...

    javaNIO学习笔记

    ### Java NIO 学习笔记 #### 一、概述 Java NIO (Non-Blocking IO,也称为 Java New IO),是 Java 对传统 IO 模型的一次重大改进,旨在提高程序处理大量并发连接的能力。NIO 的核心组件包括 Channels、Buffers 和 ...

    JAVA NIO学习笔记.docx

    import java.nio.ByteBuffer; import java.nio.channels.FileChannel; public class CopyFile { public static void main(String[] args) throws Exception { String infile = "C:\\copy.sql"; String ...

    java NIO学习系列 笔记

    Java NIO(New Input/Output)是Java标准库在JDK 1.4版本中引入的一个新特性,它提供了一种不同于传统IO流的高效I/O处理方式。NIO的核心概念包括通道(Channel)和缓冲区(Buffer),这两个组件使得数据以块的形式...

    NIO学习笔记

    《NIO学习笔记》 在Java编程领域,NIO(Non-blocking Input/Output,非阻塞I/O)是一种重要的I/O模型,与传统的BIO(Blocking I/O)相对应。NIO提供了一种新的方式来处理I/O操作,特别是在处理大量并发连接时,它的...

    阿里P8 架构师整理Java学习笔记.pdf

    ### Java学习笔记知识点总结 #### 一、JVM与内存管理 **1.1 JVM基本概念** - **JVM(Java Virtual Machine)**: Java虚拟机是执行Java字节码的虚拟机,它提供了运行Java程序所需的环境。 **1.2 线程** - **线程...

    学习笔记 java\CoreJava笔记\CoreJava_day21

    在`CoreJava_day21`的学习笔记中,主要探讨了Java中的NIO(New I/O)包及其关键类和接口,包括`ByteBuffer`、`FileChannel`以及网络编程中常用的`ServerSocket`和`Socket`等。NIO自JDK 1.4引入以来,因其高效性和...

    mina2资料-各种教程

    了解以上知识点是掌握Apache MINA的基础,通过提供的学习资料,如《Mina2.0学习笔记》、《Apache MINA入门基础》和《Apache MINA Server 2.0中文参考手册》等,可以深入学习MINA的API用法、设计原理和最佳实践。...

    nio相关知识学习

    Buffer是存储数据的容器,Java NIO提供了一系列不同类型的Buffer,如ByteBuffer、CharBuffer、IntBuffer等,它们都继承自抽象类Buffer。Selector允许单线程监控多个通道的事件,提高了程序的并发性能。 1. Channel...

    Apache mina2学习笔记DEMO

    在这个"Apache MINA2学习笔记DEMO"中,我们很可能会看到如何使用MINA来创建一个自定义协议的示例。自定义协议通常是为了满足特定应用的需求,例如高效的数据传输、安全性或者特定的编码格式。MINA允许开发者定义自己...

    极客时间《Netty源码剖析与实战》学习记录-boy-learning-netty.zip

    - **异步事件驱动**:Netty 基于非阻塞 I/O 模型,利用 Java NIO(非阻塞输入/输出)库,提高了并发性能。 - **线程模型**:Netty 使用了 EventLoop(事件循环)和 EventLoopGroup(事件循环组)来管理线程,有效...

    java常用工具类整理

    3. **java.nio.*** 包:非阻塞I/O模型,提供更高效的IO操作,如`ByteBuffer`、`Channels`和`Selectors`。 4. **java.lang.reflect.*** 包:反射机制,允许运行时动态访问和修改类、接口、字段和方法。这对于实现元...

    自动netty笔记111

    这个“自动Netty笔记111”可能是某个开发者或学习者记录的一系列关于Netty学习过程中的关键点和理解。下面将详细阐述Netty的相关知识点。 1. **异步事件驱动模型**: Netty采用了非阻塞I/O模型,基于Java NIO(Non...

    mina学习笔记,记录所有API

    在MINA的学习笔记中,记录的所有API通常会包括以下几个核心部分: 1. **IoSession**: 这是MINA的核心接口,代表了客户端和服务器之间的连接。IoSession提供了读写数据、管理连接状态、获取会话属性等功能。例如,`...

    boy-learning-netty:极客时间《 Netty原始数据解析与实战》学习记录-源码客

    4. **内存管理**:Netty使用了ByteBuf作为字节缓冲区,相比于Java NIO中的ByteBuffer,它的内存管理更加高效,减少了不必要的内存复制。 5. **线程模型**:Netty的EventLoop线程组设计确保了线程安全和性能优化,...

    learning-netty.zip

    - **ByteBuf**: Netty的高效字节缓冲区,优于Java NIO的ByteBuffer,提供了更友好的API和更好的性能。 - **Pipeline**: 事件处理链,负责在Channel中调度和执行各种I/O操作,每个Handler都可以处理特定的事件。 -...

    Mina2.0阅读源码笔记(很值得一看)

    - IoBuffer 是 Mina 中用于数据存储和传输的核心类,它是对 Java NIO ByteBuffer 的封装和增强。 - **IoBuffer vs ByteBuffer**: IoBuffer 提供了更多便于操作的功能,比如自动扩容、直接内存分配等特性,使得数据...

    netty资料.rar

    这个“netty资料.rar”压缩包文件包含了关于Netty的学习笔记,可以帮助我们深入了解Netty的核心概念和使用技巧。 Netty 的主要特点包括: 1. **异步事件驱动**:Netty 使用了非阻塞I/O模型,基于Java NIO(非阻塞...

Global site tag (gtag.js) - Google Analytics