上一篇讲到的DirectByteBuffer继承自MappedByteBuffer
一、MappedByteBuffer
MappedByteBuffer的定义:
A direct byte buffer whose content is a memory-mapped region of a file.
直接缓存,内容是一个内存映射文件。
创建测试类
public class NioTest9 {
public static void main(String[] args) throws Exception {
RandomAccessFile randomAccessFile = new RandomAccessFile("NioTest9.txt","rw");
FileChannel fileChannel = randomAccessFile.getChannel();
MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0,5);
mappedByteBuffer.put(0,(byte)'a');
mappedByteBuffer.put(3,(byte)'b');
randomAccessFile.close();
}
}
创建NioTest9.tex文件

运行程序,用记事本打开

操作的是堆外内存,堆外内存写入到文件由操作系统控制。
二、排他锁和共享锁
实际用的比较少
/**
*
* 共享锁: 所有程序都能多共享的部分进行读
* 排他锁: 只有一个程序对锁定的部分进行写操作
*
*/
public class NioTest10 {
public static void main(String[] args) throws Exception {
RandomAccessFile randomAccessFile = new RandomAccessFile("NioTest10.txt", "rw");
FileChannel fileChannel = randomAccessFile.getChannel();
FileLock fileLock = fileChannel.lock(3,6,true);
System.out.println("valid:" + fileLock.isValid());
System.out.println("lock type:" + fileLock.isShared());
fileLock.release();
randomAccessFile.close();
}
}
三、关于Buffer的Scattering(散开)与Gathering(收集)
/**
*
* 关于Buffer的Scattering(散开)与Gathering(收集)
*
*/
public class NioTest11 {
public static void main(String[] args) throws Exception {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
InetSocketAddress address = new InetSocketAddress(8899);
serverSocketChannel.socket().bind(address);
int messageLength = 2 + 3 + 4;
ByteBuffer[] buffers = new ByteBuffer[3];
buffers[0] = ByteBuffer.allocate(2);
buffers[1] = ByteBuffer.allocate(3);
buffers[2] = ByteBuffer.allocate(4);
SocketChannel socketChannel = serverSocketChannel.accept();
while (true){
int byteRead = 0;
while (byteRead < messageLength){
long r = socketChannel.read(buffers);
byteRead += r;
System.out.println("bytesRead:" + byteRead);
Arrays.asList(buffers).stream().map(buffer -> "position:" + buffer.position() +",limit:" + buffer.limit() + " 值:" + buffer.toString()).forEach(System.out::println);
}
Arrays.asList(buffers).forEach(buffer -> {
buffer.flip();
});
long byteWritten = 0;
while (byteWritten < messageLength){
long r = socketChannel.write(buffers);
byteWritten += r;
}
Arrays.asList(buffers).forEach(bufffer -> {
bufffer.clear();
});
System.out.println("bytesRead:" + byteRead + ",byteWritten: " + byteWritten +", messageLength:" + messageLength);
}
}
}
使用Telnet发送,输出结果如下图:
