channel 和 buffer
channel的主要实现类
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
buffer的主要实现类
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
- MappedByteBuffer
java channels与 传统io 流的区别
- 你可以向channle中 读或写,而流往往是单向的
- channel 的 读或写操作可以是异步的
- channel 数据 只能往buffer中 读或写
读取文件的demo
@Test
public void channelTest() throws IOException {
String path = testNio.class.getClassLoader().getResource("nio-data.txt").getPath();
RandomAccessFile aFile = new RandomAccessFile(path, "rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(128);
int bytesRead=0;
while ((bytesRead=(inChannel.read(buf)))!= -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();
}
buffer方法
向buffer中写入数据
- 从channel向buffer写入数据
int bytesRead = inChannel.read(buf); //read into buffer.
- 执行put方法
buf.put(127);
从buffer中读取数据
- 从buffer中读取数据写入channel
//read from buffer into channel.
int bytesWritten = inChannel.write(buf);
- 执行get()方法
byte aByte = buf.get();
clear() and compact()的区别
相同:都用来使buffer准备好下一次写入
完成从缓冲区读取数据后,必须使缓冲区准备好再次写入。你可以通过调用clear()或调用compact()来实现。
不同点:对待未读取数据的处理方式不同
如果缓冲区中仍有未读数据,并且您想稍后读取它,但您需要先进行一些写入,请调用compact()而不是clear()。
compact()将所有未读数据复制到Buffer的开头。然后它将位置设置在最后一个未读元素之后。 limit属性仍设置为capacity,就像clear()一样。现在缓冲区已准备好写入,但您不会覆盖未读数据,此时buffer又处于等待写入状态
equals() and compareTo()区别
equals方法:
- buffer类型一致
- 有同样数量的剩余元素在buffer中
- 所有剩余元素都是equal的
所以equals()方法只能比较buffer中的部分元素,而不是buffer中的每一个元素
compareTo()方法
比较buffer中的所有元素
buffer判断大小依据:
- The first element which is equal to the corresponding element in the other buffer, is smaller than that in the other buffer.
- All elements are equal, but the first buffer runs out of elements before the second buffer does (it has fewer elements).
java NIO Scatter/Gather
Scatter:将数据写到多个buffer中,对消息体大小不固定的数据不太好用
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] bufferArray = { header, body };
channel.read(bufferArray);
Gather:
从多个buffer中收集数据,写到channel中
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
//write data into buffers
ByteBuffer[] bufferArray = { header, body };
channel.write(bufferArray);