例如:要创建一个映射到数组位置12-20(9个元素)的buffer对象:
char[] myBuffer = new char[100]; CharBuffer cb = CharBuffer.wrap(myBuffer); cb.position(12).limit(21); CharBuffer sliced = cb.slice();
3、字节缓冲区
虽然我们有很多缓冲区类型,除了boolean型都有一一对应。
但是,ByteBuffer作为一个基本的缓冲区,其作用非同寻常。我们的通道只和字节缓冲区打交道。并且,其他的缓冲区和字节缓冲区都可以转换。
说到这里,我们就不得不理解计算机如何存储数据了。
实际上,内存是按照字节为单位来存放数据的。现在最流行的便是8个位一个字节。我们熟悉的是int占用4个字节,这样,这四个字节如何排列,又成为一个问题。
这个问题已经是硬件问题了,因为不同的硬件有不同的表现。
对于intel处理器,一般都是小端(little endian)
而对于摩托罗拉,Sun的处理器,一般都是大端(big endian)
还有网络字节顺序实际上也是大端的。
那么这两者有什么区别呢?
假设 一个int值 0x01234567 (注意是16进制),内存从左到右增长。地址左小右大
那么他在大端的存放 就类似 : 0x01 0x23 0x45 0x67
那么他在小端的存放,就应该是: 0x67 0x45 0x23 0x01
所以我们的字节操作中有了顺序问题。
package java.nio;
public final class ByteOrder
{
public static final ByteOrder BIG_ENDIAN;
public static final ByteOrder LITTLE_ENDIAN;
public static ByteOrder nativeOrder();
public String toString();
}
在JVM中,实际上我们是使用大端的。
看看关于Order的操作。
public abstract class ByteBuffer extends Buffer
implements Comparable {
// This is a partial API listing
public final ByteOrder order();
public final ByteBuffer order(ByteOrder bo);
}
order返回系统使用的字节顺序。注意如果系统字节顺序和JVM不一致,可能性能上会有些许慢。
现在知道了字节顺序,那么字节缓冲区转换为其他缓冲区,也就清楚了。
比如,我们有一个4字节缓冲区 0x01 0x23 0x45 0x67
转换为一个IntBuffer,那么,根据字节顺序,如果是大端,直接就是 0x1234567
如果是小端顺序,那么读出来就是 0x67452301
注意:视图缓冲区一旦创建,字节顺序是不可改变的。视图缓冲区后面讲到。
4、直接缓冲区
前面说到,allocate和wrap创建的都是间接缓冲区。地区分类 数组间接缓冲区,就是在操作系统和JVM之间其实有一层,我们如果对一个间接缓冲区使用,那么首先是要在操作系统层次创建一个临时缓冲区,然后copy过去,再操作,在删除临时缓冲区。这都很麻烦。地区分类 数组
所以,直接缓冲区。也就是在操作系统,而不是JVM进程中创建缓冲区,这就绕过了JVM栈,所以依赖于具体的操作系统。事实上,在操作系统中创建缓冲区,比起在JVM中,更加消耗资源。(因为JVM中是已经划分好的内存,直接设置一下,而操作系统中要通过系统调用,个人理解。)
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-32465-3.html
声音太好听
有导弹和相控雷迏了却不敢打仗了
人一身只要你努力就可以拼搏你想要的