天天看點

學習 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()