ByteBuffer有两个创建缓冲区的方法:
static ByteBuffer allocate(int capacity)
static ByteBuffer allocateDirect(int capacity)
  这两个方法都是创建缓冲区的方法,使用直接缓冲区的时候,JVM虚拟机会直接在此缓冲区上执行本机IO操作,也就是说,在每次调用基础操作系统的一个本机IO之前或者之后,虚拟机都会避免将缓冲区的内容复制到中间缓冲区(或者从中间缓冲区复制内容)。 直接字节缓冲区使用上边方法中的allocateDirect工厂方法创建,此方法返回的缓冲区进行分配和取消分配所需要的成本往往比间接缓冲区要高,直接缓冲区的内容可以驻留 在常规的垃圾回收堆之外,因此,它们对应用程序的内容需求量造成的影响可能并不明显,所以建议将直接缓冲区主要分配给那些容易受基础系统的本 机IO操作影响的大型、持久的缓冲区。一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处的时候分配它们。
  直接缓冲区还可以使用mapping 将文件区域直接映射到内存中来创建,Java平台的实现有助于通过JNI从本机代码直接创建字节缓冲区,如果以上这些缓冲区中的某个缓冲区实例指的是不可 访问的内存区域,则视图访问该区域不会更改该缓冲区的内容,并且会在访问期间或稍候的某个时间导致抛出不确定的异常。
  字节缓冲区是直接缓冲区还是非直接缓 冲区可以通过ByteBuffer的isDirect方法来确定,提供该方法是为了能够在性能关键型代码中执行显示缓冲区管理。
  访问二进制数据:
  此类定义除了boolean之外,读写所有其他基本类型值的方法,这些基本值可 以根据缓冲区的当前字节顺序与字节序列相互进行转换,并可以通过order方法获取和修改。特定的字节顺序由ByteOrder类的实例进行表示,字节缓 冲区的初始顺序是BIG_ENDIAN(该顺序可以参考《Java内存模型》http://blog.csdn.net/silentbalanceyh/archive/2009/10/13/4661230.aspx)的。为了访问异类二进制数据,此类还针对每种类型定义了一系列绝对和相对的put和get方法, 并针对float、 char、short、int、long和double等类型定义了相对方法,该方法可以自行参考API内容。绝对get和put方法的 index参数是根据字节定义的,而不是根据所读写的类型定义的。
  为了访问同类二进制数据(即相同类型的值序列),此类还定义了可 以为指定类型的缓冲区创建视图的方法,视图缓冲区只是其内容受该字节缓冲区支持的另一种缓冲区,字节缓冲区内容的更改在视图缓冲区中是可见的,反之亦然;这两种缓冲区的位置、限制和标记 值都是独立的。使用视图缓冲区有三大优势:
视 图缓冲区不是根据字节进行索引,而是根据其特定于类型的值的大小进行索引
视 图缓冲区提供了相对批量put和get方法,这些方法可在缓冲区和数组或相同类型的其他缓冲区之间传输值的连续序列
视图缓冲区可能更高效,这是因为,当且仅当其支持的字节缓冲区为直接缓冲区时它才是直接缓冲区。
  实际上ByteBuffer是继承于Buffer类,里面存放的是字节,如果要 将它们转换成字符串则需要使用Charset,Charset是字符编码,它提供了把字节流转换成为字符流(解码)和 将字符串转换成字节流(编码)的方法。该类有一下三个重要的属性:
容量(capacity):表示该缓冲区可以存放多少数据
极限(limit):表示读写缓存的位置, 不能对超过位置进行数据的读或写操作
位置(position):表示下一个缓冲区的读写单元, 每读写一次缓存区,位置都会变化,位置是一个非负整数

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
  
public class QuickCopy {
    public static void main(String args[]) throws Exception{
        FileInputStream fin = new FileInputStream("D:/work/test.txt");
        FileOutputStream fout = new FileOutputStream("D:/work/output.txt");
        FileChannel inChannel = fin.getChannel();
        FileChannel outChannel = fout.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while(true){
            int ret = inChannel.read(buffer);
            if( ret == -1)
                break;
            buffer.flip(); //该方法为父类Buffer的方法
            outChannel.write(buffer);
            buffer.clear(); //该方法为父类Buffer的方法
        }
    }
}

  上边的代码分配了1024个字节的直接缓冲区,然后使用本地拷贝的方式进行文件拷贝,应该是比 普通的文件拷贝更高效,这里解释几个比较常用的ByteBuffer类里面的方法【这里不介绍分配缓冲区的方法 了】:
public abstract ByteBuffer compact() throws ReadOnlyBufferException:
——该方法压缩此缓冲区(可选的),将缓冲区的当前位置和界限之间的字节复制到缓冲区的开始处,即将索引p = position()处 的字节复制到索引0处,将索引n+1处的字节复制到索引1的 位置,依次类推直到索引limit() - 1处的字节复制到索引 n = limit() - 1 - p处, 然后将缓冲区的位置设置为n + 1,并将其界限设置为其容量,如果已定义了标记,则丢弃。将缓冲区的位置设置为复制的字节数,而不是零,以便调 用此方法后可以紧接着调用另一个相对put方法。
public abstract ByteBuffer duplicate():
——创建共享此缓冲区内容的新的字节缓冲区,新缓冲区的内容将为此缓冲区的内容,此缓冲区内容的更改在新缓冲 区中是可见的,反之亦然;这两个缓冲区的位置、界限和标记值是相互独立的。新缓冲区的容量、界限、位置和标记值将与此缓冲区相同。当且 仅当此缓冲区为直接时,新缓冲区才是直接的,当切仅当此缓冲区是只读时,新缓冲区才是只读的。
public abstract ByteBuffer slice():
——创建新的字节缓冲区,其内容是此缓冲区的共享子序列,新缓冲区的内容将从此缓冲区的当前位置开始,此缓冲 区内容的更改在新缓冲区中是可见的,反之亦然;这两个缓冲区的位置、界限和标记值是相互独立的。
public abstract ByteBuffer wrap(byte[] array):
——将byte数组包装到缓冲区中,新的缓冲区将由给定的byte数组支持,也就是说,缓冲区修改 将导致数组修改,反之亦然。新缓冲区的容量和界限将为array.length,其位置将为零,其标记是不确定的,其底层实现数据将为给定数组,并且其数 组偏移量将为零。
  这里再提供几个基本操作的例子:

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
 
public class BasicType {
    public static void main(String args[]) throws Exception{
        // 使用字节数组创建ByteBuffer
        byte[] bytes = new byte[10];
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        // 创建字符ByteBuffer
        ByteBuffer charBuffer = ByteBuffer.allocate(15);
        CharBuffer charBuffer2 = buffer.asCharBuffer();
        // 设置获取字符类型的Buffer
        ByteBuffer charBuffer3 = ByteBuffer.allocate(100);
        charBuffer3.putChar((char)123);
        charBuffer3.flip();
        char c = charBuffer3.getChar();
    }
}

  上边是针对基本类型的操作,查阅API可以看到基本操作相关的类里面提供的方法

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
 
public class StringByteBuffer {
    public static void main(String args[]) throws Exception{
        // 使用ByteBuffer存储字符串
        ByteBuffer buffer = ByteBuffer.allocate(100);
        CharBuffer cBuffer = buffer.asCharBuffer();
        cBuffer.put("Hello World");
        cBuffer.flip();
        String result = cBuffer.toString();
    }
} 2013-01-13 名品推荐:潮顺品 榕宜 灵澜

java NIO 直接与非直接缓冲区的更多相关文章

  1. Java NIO -- 阻塞和非阻塞

    传统的 IO 流都是阻塞式的.也就是说,当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务.因此,在完成网络通信进行 IO操作 ...

  2. Java NIO: Non-blocking Server 非阻塞网络服务器

    本文翻译自 Jakob Jenkov 的 Java NIO: Non-blocking Server ,原文地址:http://tutorials.jenkov.com/java-nio/non-bl ...

  3. Java NIO(二)缓冲区

    概念 缓冲区:一个用于特定基本数据类型的容器,由java.nio包定义的所有缓冲区都是Buffer抽象类的子类.其作用于与NIO的通道进行交互,数据从通道读入缓冲区,数据从缓冲区写入通道 Buffer ...

  4. Java NIO ———— Buffer 缓冲区详解 入门

    引言缓冲区是一个用于特定基本类型的容器.由java.nio 包定义,所有缓冲区都是 Buffer 抽象类的子类. Java NIO 中的 Buffer ,主要用于与NIO 通道进行交互.数据从通道存入 ...

  5. Java NIO入门(二):缓冲区内部细节

    Java NIO 入门(二)缓冲区内部细节 概述 本文将介绍 NIO 中两个重要的缓冲区组件:状态变量和访问方法 (accessor). 状态变量是前一文中提到的"内部统计机制"的 ...

  6. Java NIO 之 Buffer(缓冲区)

    一 Buffer(缓冲区)介绍 Java NIO Buffers用于和NIO Channel交互. 我们从Channel中读取数据到buffers里,从Buffer把数据写入到Channels. Bu ...

  7. java nio使用方法(转)

    最近由于工作关系要做一些Java方面的开发,其中最重要的一块就是Java NIO(New I/O),尽管很早以前了解过一些,但并没有认真去看过它的实现原理,也没有机会在工作中使用,这次也好重新研究一下 ...

  8. Java NIO学习笔记一 Java NIO概述

    Java NIO概述 Java NIO(新的IO)是Java的替代IO API(来自Java 1.4),这意味着替代标准的 java IO和java Networking API.Java NIO提供 ...

  9. Java NIO 概览

    Java面试通关手册(Java学习指南) Github地址:https://github.com/Snailclimb/Java_Guide 一 NIO简介 Java NIO 是 java 1.4 之 ...

随机推荐

  1. 计算机网络什么是OSI7层模型、TCP/IP4层模型理解

    模型图解 应用层 就是最顶层的.通常指的应用程序初始走的协议比如有 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层 主要对数据应用层的数据包进行加密 会话层 建立.管理. ...

  2. Unity 敌人波次设计

    一.平均时间随机敌人 将所有种类敌人预制物体放在一个列表里面,每隔时间T从列表中随机选出一个生成在场景中. 二.时间加权紧迫度随机敌人 在随机情况下每种敌人出现的概率近似相等,当敌人种类较多时,有可能 ...

  3. Daily Scrum 12-25

    Meeting Minutes 针对设计师提出的问题完成了layout的微调: 讨论alpha测试反馈反映出的一些问题: 完成了代码的merge(与bing词典 1.5版本): Progress   ...

  4. NopCommerce源码架构

    我们承接以下nop相关的业务,欢迎联系我们. 我们承接NopCommerce定制个性化开发: Nopcommerce二次开发 Nopcommerce主题开发 基于Nopcommerce的二次开发的电子 ...

  5. Spring及Spring Boot 国内快速开发框架

    http://www.javacoder.top/home.jsp# http://springboot.fun/ 一个常用的支付子项目 https://gitee.com/52itstyle/spr ...

  6. [转帖]nginx upstream模块--负载均衡

    nginx upstream模块--负载均衡 https://www.cnblogs.com/linjiqin/p/5494783.html Module ngx_http_upstream_modu ...

  7. Oracle测试环境参数调整.

    测试环境上面Oracle数据库性能参数设置 1. 关闭回收站 alter system set recyclebin=off 2. 修改redo日志的大小 11g的默认大小是50m 如果redo fi ...

  8. [读书笔记]Linux命令行与shell编程读书笔记01

    1. Linux的组成部分 1)linux内核(kernel) 2)GNU工具链 3)GUI/CLI工作几面(shell) 4)应用程序(app) 2Linux内核的主要工作: 1) 管理内存 2)管 ...

  9. 自省 另外一种python 生成随机在base36 之间的兑换码生成。

    放假无聊,翻看自己博客的时候发现自己前面写的 那个base36兑换码在翻阅的时候 想到一个更简单的办法实现.但是随机上来说可能没有前者那么高 但是觉得也没有多大的问题 发上来 自己再想想 import ...

  10. LinkedList 实现 Queue

    package cn.com.example; import java.util.LinkedList; /** * Created by Jack on 2017/3/8. */ public cl ...