`
美丽的小岛
  • 浏览: 309344 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

Buffer类与ByteBuffer类(来自JDK)

    博客分类:
  • java
 
阅读更多

1.         Bufferpublic abstract class Buffer extends Object

直接已知子类:

ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer

一个用于特定基本类型数据的容器。

缓冲区是特定基本类型元素的线性有限序列。除内容外,缓冲区的基本属性还包括容量、限制和位置:

缓冲区的容量 是它所包含的元素的数量。缓冲区的容量不能为负并且不能更改。

缓冲区的限制 是第一个不应该读取或写入的元素的索引。缓冲区的限制不能为负,并且不能大于其容量。

缓冲区的位置 是下一个要读取或写入的元素的索引。缓冲区的位置不能为负,并且不能大于其限制。

对于每个非 boolean 基本类型,此类都有一个子类与之对应。

传输数据

此类的每个子类都定义了两种获取 放置 操作:

相对 操作读取或写入一个或多个元素,它从当前位置开始,然后将位置增加所传输的元素数。如果请求的传输超出限制,则相对获取 操作将抛出 BufferUnderflowException,相对放置 操作将抛出 BufferOverflowException;这两种情况下,都没有数据被传输。

绝对 操作采用显式元素索引,该操作不影响位置。如果索引参数超出限制,绝对获取 操作和放置 操作将抛出 IndexOutOfBoundsException

当然,通过适当通道的 I/O 操作(通常与当前位置有关)也可以将数据传输到缓冲区或从缓冲区传出数据。

做标记和重置

缓冲区的标记 是一个索引,在调用 reset 方法时会将缓冲区的位置重置为该索引。并非总是需要定义标记,但在定义标记时,不能将其定义为负数,并且不能让它大于位置。如果定义了标记,则在将位置或限制调整为小于该标记的值时,该标记将被丢弃。如果未定义标记,那么调用 reset 方法将导致抛出 InvalidMarkException

不变式

标记、位置、限制和容量值遵守以下不变式:

0 <= 标记 <= 位置 <= 限制 <= 容量

新创建的缓冲区总有一个 0 位置和一个未定义的标记。初始限制可以为 0,也可以为其他值,这取决于缓冲区类型及其构建方式。一般情况下,缓冲区的初始内容是未定义的。

清除、反转和重绕

除了访问位置、限制、容量值的方法以及做标记和重置的方法外,此类还定义了以下可对缓冲区进行的操作:

  • clear() 使缓冲区为一系列新的通道读取或相对放置 操作做好准备:它将限制设置为容量大小,将位置设置为 0
  • flip() 使缓冲区为一系列新的通道写入或相对获取 操作做好准备:它将限制设置为当前位置,然后将位置设置为 0
  • rewind() 使缓冲区为重新读取已包含的数据做好准备:它使限制保持不变,将位置设置为 0

只读缓冲区

每个缓冲区都是可读取的,但并非每个缓冲区都是可写入的。每个缓冲区类的转变方法都被指定为可选操作,当对只读缓冲区调用时,将抛出 ReadOnlyBufferException。只读缓冲区不允许更改其内容,但其标记、位置和限制值是可变的。可以调用其 isReadOnly 方法确定缓冲区是否为只读。

线程安全

多个当前线程使用缓冲区是不安全的。如果一个缓冲区由不止一个线程使用,则应该通过适当的同步来控制对该缓冲区的访问。

调用链

指定此类中的方法返回调用它们的缓冲区(否则它们不会返回任何值)。此操作允许将方法调用组成一个链;例如,语句序列

 b.flip();

 b.position(23);

 b.limit(42);

可以由以下更紧凑的一个语句代替

 b.flip().position(23).limit(42);

2.         public abstract class ByteBuffer extends Buffer implements Comparable<ByteBuffer> 字节缓冲区。

此类针对字节缓冲区定义了以下六类操作:

  • 读写单个字节的绝对和相对 get put 方法;
  • 将此缓冲区的连续字节序列传输到数组中的相对批量 get 方法;
  • byte 数组或其他字节缓冲区中的连续字节序列传输到此缓冲区的相对批量 put 方法;
  • 读写其他基本类型值,并按照特定的字节顺序在字节序列之间转换这些值的绝对和相对 get put 方法;
  • 创建视图缓冲区 的方法,这些方法允许将字节缓冲区视为包含其他基本类型值的缓冲区;
  • 对字节缓冲区进行 compactingduplicating slicing 的方法。

字节缓冲区可以通过 allocation 方法创建,此方法为该缓冲区的内容分配空间,或通过 wrapping 方法将现有的 byte 数组包装到缓冲区中来创建。

直接 非直接缓冲区

字节缓冲区要么是直接的,要么是非直接的。如果为直接字节缓冲区,则 Java 虚拟机会尽最大努力直接在此缓冲区上执行本机 I/O 操作。也就是说,在每次调用基础操作系统的一个本机 I/O 操作之前(或之后),虚拟机都会尽量避免将缓冲区的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)。

直接字节缓冲区可以通过调用此类的 allocateDirect 工厂方法来创建。此方法返回的缓冲区进行分配和取消分配所需成本通常高于非直接缓冲区。直接缓冲区的内容可以驻留在常规的垃圾回收堆之外,因此,它们对应用程序的内存需求量造成的影响可能并不明显。所以,建议将直接缓冲区主要分配给那些易受基础系统的本机 I/O 操作影响的大型、持久的缓冲区。一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处时分配它们。

直接字节缓冲区还可以通过 mapping 将文件区域直接映射到内存中来创建。Java 平台的实现有助于通过 JNI 从本机代码创建直接字节缓冲区。如果以上这些缓冲区中的某个缓冲区实例指的是不可访问的内存区域,则试图访问该区域不会更改该缓冲区的内容,并且将会在访问期间或稍后的某个时间导致抛出不确定的异常。

字节缓冲区是直接缓冲区还是非直接缓冲区可通过调用其 isDirect 方法来确定。提供此方法是为了能够在性能关键型代码中执行显式缓冲区管理。

访问二进制数据

此类定义了除 boolean 之外,读写所有其他基本类型值的方法。这些基本值可以根据缓冲区的当前字节顺序与字节序列互相进行转换,并可以通过 order 方法获取和修改。特定的字节顺序由 ByteOrder 类的实例表示。字节缓冲区的初始顺序始终是 BIG_ENDIAN

为了访问异类二进制数据(即其他类型的值的序列),此类还针对每种类型定义了一系列绝对和相对的 get put 方法。例如,对于 32 位浮点值,此类定义了以下方法:

 float  getFloat()

 float  getFloat(int index)

  void  putFloat(float f)

  void  putFloat(int index, float f)

并针对 charshortintlong double 等类型定义了相应的方法。绝对 get put 方法的 index 参数是根据字节定义的,而不是根据所读写的类型定义的。

为了访问同类二进制数据(即相同类型的值的序列),此类还定义了可以为指定类型的缓冲区创建视图 的方法。视图缓冲区 只是其内容受该字节缓冲区支持的另一种缓冲区。字节缓冲区内容的更改在视图缓冲区中是可见的,反之亦然;这两种缓冲区的位置、限制和标记值都是独立的。例如,asFloatBuffer 方法将创建 FloatBuffer 类的一个实例,该类受在其上调用该方法的字节缓冲区的支持。该类将为 charshortintlong double 等类型定义相应的视图创建方法。

与上述特定于类型的 get put 方法系列相比,视图缓冲区有以下三大主要优势:

  • 视图缓冲区不是根据字节进行索引,而是根据其特定于类型的值的大小进行索引;
  • 视图缓冲区提供了相对批量 get put 方法,这些方法可在缓冲区和数组或相同类型的其他缓冲区之间传输值的连续序列;
  • 视图缓冲区可能更高效,这是因为,当且仅当其支持的字节缓冲区为直接缓冲区时它才是直接缓冲区。

视图缓冲区的字节顺序固定为创建该视图时其字节缓冲区的字节顺序。

调用的链接

指定此类中的方法(它们不返回其他值),以返回这些方法被调用时所在的缓冲区。这允许对方法调用进行链接。 例如,语句序列

 bb.putInt(0xCAFEBABE);

 bb.putShort(3);

 bb.putShort(45);

可以由以下单个语句替换

 bb.putInt(0xCAFEBABE).putShort(3).putShort(45);

 

分享到:
评论

相关推荐

    jdk 7 源码。含sun包下所有源码

    《深入解析JDK 7源码:聚焦sun包下的核心组件与nio》 JDK(Java Development Kit)是Java开发者的必备工具,其中包含了Java运行环境、编译器以及各种API。JDK 7作为Java的重要版本,引入了许多新特性,优化了性能,...

    jdk jdk jdk

    Buffer 中有多种类型,例如 ByteBuffer、CharBuffer、DoubleBuffer 等,每种类型都对应一个 primitive type 数据。ByteBuffer 是其中最重要的一个子类,因为在 java.io.channels 中定义的各种 channel 的 IO 操作...

    Java JDK 1.4 Tutorial

    在Java JDK 1.4中,NIO框架被引入,这是一个处理文件和网络数据的新方式,它提供了与流API不同的接口和类。NIO支持基于通道(channel)和缓冲区(buffer)的I/O操作,使得程序可以更高效地处理大量数据。例如: - **...

    JDK_7_NIO2

    ### JDK 7 NIO2 新特性详解 #### 引言 随着 Java 7 的发布,NIO (New I/O) 接口迎来了重要的更新,即 NIO.2 或称为 MNI (More New I/O)。NIO.2 增强了 Java 1.4 中的 NIO API,为开发人员提供了更为强大的 I/O ...

    最新JDK教程(CHM版)

    - **线程模型的增强**:JDK 5.0之后引入了更高级的并发工具类,如`ConcurrentHashMap`等。 #### 三、集合框架 - **概述**:Java集合框架提供了一组接口和实现类,用于存储和操作对象集合。 - **Collection接口**:...

    jdkapi140

    3. **枚举类型(Enum)**:虽然枚举在JDK 5.0中才正式成为关键字,但JDK 1.4.0已经引入了初步的支持,通过`java.lang.reflect.Enum`类实现。这种早期的枚举方式为后续的枚举语法奠定了基础。 4. **集合框架增强**:...

    jdk1.6 源码 包含nio等

    Java NIO提供了一系列的缓冲区类,如ByteBuffer、CharBuffer、IntBuffer等,用于不同数据类型的存储。缓冲区有特定的方法用于读写数据,如put()和get()。 3. **选择器(Selector)**:选择器允许单个线程监视多个通道...

    java.nio API详解

    ByteBuffer是NIO中的关键类,它与其他类型的Buffer(如CharBuffer、IntBuffer等)一样,具有capacity、limit和position属性。但是,ByteBuffer与Channel和Selector的交互更加紧密。例如,可以从FileChannel中读取...

    Java_NIO_API详解

    #### 三、Buffer与ByteBuffer **Buffer**是NIO API的核心概念之一,它定义了一个线性的原始类型数据容器接口。每种原始类型(除`boolean`外)都有一个对应的Buffer子类,如`ByteBuffer`、`CharBuffer`等。这些...

    mldn nio ppt 源码

    1. **Buffer类的使用**:Buffer类包括ByteBuffer、CharBuffer、IntBuffer等,它们提供了put和get方法进行数据的读写。源码会展示如何创建Buffer,填充数据,以及如何从Buffer中读取数据。 2. **Channel接口的实现**...

    jdk6.0从入门到精通-----chapter5网络编程 新I/O(含源码下载)

    4. **ByteBuffer**:用于读写数据的缓冲区,`ByteBuffer.allocate()`分配内存,`buffer.put()`写入数据,`buffer.flip()`切换到读模式,`buffer.get()`读取数据。 5. **FileChannel**:用于文件操作的通道,可以...

    java NOI 学习

    此外,`ByteBuffer`是`Buffer`的一个重要子类,它主要用于与`Channel`交互。`ByteBuffer`支持多种创建方式: - `ByteBuffer.allocate(int capacity)`:创建一个具有指定容量的`ByteBuffer`。 - `ByteBuffer....

    Java IO

    1. NIO.2的介绍与重要性:在Java 7中预期发布的JSR-203,即NIO.2,是对之前NIO(JSR-51)的扩展和补充,它添加了许多新特性,比如新的文件系统API、异步I/O、更新的Buffer类和新的网络通道接口等。 2. Java NIO的...

    学习笔记 java\CoreJava笔记\CoreJava_day21

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

    Java nio详细介绍 详细介绍java nio

    - **类层次结构**:NIO为所有的原始数据类型提供了`Buffer`的支持,例如`ByteBuffer`、`CharBuffer`等。这些类继承自抽象基类`Buffer`。 - **关键子类**:`MappedByteBuffer`是`ByteBuffer`的子类,支持文件内存...

    JAVA NIO学习笔记.docx

    Java NIO(New Input/Output)是Java标准库在JDK 1.4引入的一组新的I/O API,它提供了一种不同于传统IO的高效、非阻塞的I/O操作方式。NIO的核心概念包括Channel、Buffer和Selector,它们共同构建了一个与操作系统...

    java 之异步套接字编程实例(AIO)

    Java中的异步套接字编程,也称为非阻塞I/O(Non-blocking I/O, NIO)或异步I/O(Asynchronous I/O, AIO),是Java在JDK 7引入的一种高级I/O模型,它极大地提高了网络编程的效率。AIO的主要目标是提供一种方法,使得...

    java NIO 详细讲解

    - **API设计**:NIO引入了`Channel`和`Buffer`等核心概念,而传统IO主要依赖于`InputStream`和`OutputStream`等流类。 #### 三、核心概念:通道(Channel)与缓冲区(Buffer) ##### 3.1 概述 - **通道(Channel)**:...

    JAVANIO简介.pdf

    ByteBuffer buffer = ByteBuffer.allocate(1024); while (true) { buffer.clear(); int r = fcin.read(buffer); if (r == -1) { break; } buffer.flip(); fcout.write(buffer); } } } ``` 在此...

Global site tag (gtag.js) - Google Analytics