天天看点

学习 NIO ,NIO 中 buffer 和 channel 的基本用法

这篇博客为个人学习小结,因此不大注重博客的美观。

文件流.getChannel()

fileChannel 将buffer的数据写入文件
fileChannel 将文件的数据读入buffer

拷贝
fileChannel1将文件的数据读入buffer
fileChannel2将buffer的数据写入文件

两个fileChannel之间传输文件
targetChannel.transferFrom(sourceChannel,0,sourceChannel.size());
或
sourceChannel.transferTo(0,sourceChannel.size(),targetChannel);


byteBuffer 可以类型化的读取
byteBuffer.putInt(123);
byteBuffer.putDouble(6.66);
byteBuffer.flip();
byteBuffer.getInt(123);
byteBuffer.getDouble(6.66);
按顺序读取,顺序错误则数据错误
如果越界,报异常
BufferUnderflowException

可以转为只读buffer
byteBuffer.asReadOnlyBuffer();


在堆外内存修改文件,配置映射,NIO完成文件的同步
new RandomAccessFile("1.txt", "rw").getChannel();
randomAccessFileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
mappedByteBuffer.put(0,(byte) 'H');
randomAccessFile.close();

byteBuffer 常用方法
ByteBuffer.allocate(5);
byteBuffer.wrap(byte[]);
byteBuffer.wrap(byte[],offset,length);

byteBuffer.capacity();
byteBuffer.position();
byteBuffer.position(3);
byteBuffer.limit();
byteBuffer.limit(4);

byteBuffer.flip();
byteBuffer.clear();

byteBuffer.put();
byteBuffer.put(byte[]);
byteBuffer.put(byte[],offset,length);
byteBuffer.get();
byteBuffer.gett(byte[]);
byteBuffer.get(byte[],offset,length);

FileChannel,SocketChannel,ServerSocketChannel
的read和write支持buffer数组

简单的NIO群聊程序
ServerSocketChannel
绑定端口,配置非阻塞,注册进Selector
循环select(),有事件时依次处理,selector.selectedKeys().iterator()
accept(),设置非阻塞,注册
读数据,key.channel()
群发消息,跳过发送者和服务器
selector.keys()
读数据过程中有异常 可能是客户端下线
iterator.remove()删除每个SelectionKey

SocketChannel
绑定主机,端口,配置非阻塞,注册进自己的selector
循环select(),依次处理事件并删除key

SelectionKey常用方法
selector() 关联的selector
channel() 关联的schannel
attachment() 关联的关系数据,可用Buffer,返回Object
interestOps 设置或改变监听事件
isAcceptble()
isReadable()
isWritable()

ServerSocketChannel
open();
socket().bind();
configureBlocking();
register();
accept();
close()

SocketChannel
open();
configureBlocking();
connect();
finishConnect()
register();
read()
write()
close()

Selector
open()
keys()
selectedKeys()
select()
select(2000)
selectNow()
close()