从C那边转过来学习java 的NIO,相对来说还是容易些。也更愿意把C底层的socket和Java NIO做些比较。
Java NIO的核心部件:
Channels对应于socket 的文件句柄
Selectors对应于socket的select函数
Buffers对应于socket的内存,通常即读写socket的void 数组。
Channel 包含:
DatagramChannel (TCP)
SocketChannel (UDP)
FileChannel(File)
ServerSocketChannel
Buffer方法:
flip()方法,从写模式转换到读模式
clear()方法,清除所有数据。 compact清除已经读过的数据。
Buffer的三个属性值:
capacity buf申请的内存大小
position 当前位置
limit 写时等于capacity,读时为写的数据大小
rewind方法使得position 为0
mark,reset,打记号
Buffer 类型:
ByteBuffer
MappedByteBuffer
CharBuffer
DoubleBuffer
FloatBuffer
IntBuffer
LongBuffer
ShortBuffer
Buffer分配:
allocate方法
Buffer读写方法:
int bytesRead = inChannel.read(buf); //read into buffer.
buf.put(127);
int bytesWritten = inChannel.write(buf);
byte aByte = buf.get();
Channel分散读,聚集写:
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = {header,body};
channel.read(bufferArray);
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = {header,body};
channel.write(bufferArray);
demo:
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ChannelTest {
public static void main(String args[]) throws IOException
{
RandomAccessFile aFile = new RandomAccessFile("/home/violation.network.1446106703.ing", "r");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
while (bytesRead != -1)
{
System.out.println("Read " + bytesRead);
buf.flip();
while(buf.hasRemaining()){
System.out.print((char) buf.get());
}
buf.clear();
bytesRead = inChannel.read(buf);
}
aFile.close();
}
}