Buffer的capacity,limit,position
limit,position的含义取决于是读模式还是写模式
capacity
buffer的大小
limit
write:和capacity一样,表示能写多少
read:表示最多可读多少
position
write:write index,最大值 capacity-1
read:read index,从写模式切换到读模式时,position会被重置为0
buffer的类型
- ByteBuffer
- MappedByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
public class FileTest { public static void main(String[] args) throws IOException { RandomAccessFile raFile = new RandomAccessFile("/Users/shifulong/monitor_contact.sql", "rw"); FileChannel fileChannel = raFile.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(64); while (fileChannel.read(byteBuffer) != -1) {//read in to buffer byteBuffer.flip(); while (byteBuffer.hasRemaining()) { System.out.print((char) byteBuffer.get()); } byteBuffer.clear(); } } }
典型的几个方法
ByteBuffer byteBuffer = ByteBuffer.allocate(64);//获取一个64大小的buffer byteBuffer.flip();//将buffer从写模式切换到读模式 byteBuffer.rewind();//将position设为0,可重读数据 byteBuffer.clear();//清除buffer position设为0,如果buffer中还有数据没有读,就丢失了 byteBuffer.compact();//清除buffer,并把没读的数据copy到起始处,position设到最后一个没读的数据后面,可以追加写 byteBuffer.mark();//标记一个特定postion byteBuffer.reset();//恢复标记,恢复到标记的position
分散&聚集
多个buffer写到channel中
从channel总读到多个buffer中
//分散 public void scatter() throws IOException { RandomAccessFile randomAccessFile = new RandomAccessFile("", ""); FileChannel fileChannel = randomAccessFile.getChannel(); ByteBuffer head = ByteBuffer.allocate(16); ByteBuffer body = ByteBuffer.allocate(64); fileChannel.read(new ByteBuffer[]{head, body});//读到多个buffer中,不方便操作不定长的消息 } //聚集 public void gather() throws IOException { RandomAccessFile randomAccessFile = new RandomAccessFile("", ""); FileChannel fileChannel = randomAccessFile.getChannel(); ByteBuffer buffer1 = ByteBuffer.allocate(16);//need put byte to buffer ByteBuffer buffer2 = ByteBuffer.allocate(64); fileChannel.write(new ByteBuffer[]{buffer1, buffer2});//多个buffer写到channel,可以操作不定长的消息 }
通道之间的数据传输
只要两个通道之间有一个是FileChannel,就可以将一个channel传输到另一个channel
public static void from() throws IOException { RandomAccessFile fromFile = new RandomAccessFile("/Users/shifulong/monitor_contact.sql", "rw"); FileChannel fromChannel = fromFile.getChannel(); RandomAccessFile toFile = new RandomAccessFile("/Users/shifulong/monitor_contact_to.sql", "rw"); FileChannel toChannel = toFile.getChannel(); long position = 0; toChannel.transferFrom(fromChannel,position,fromChannel.size()); toChannel.close(); fromChannel.close(); } public static void to() throws IOException { RandomAccessFile fromFile = new RandomAccessFile("/Users/shifulong/monitor_contact.sql", "rw"); FileChannel fromChannel = fromFile.getChannel(); RandomAccessFile toFile = new RandomAccessFile("/Users/shifulong/monitor_contact_to.sql", "rw"); FileChannel toChannel = toFile.getChannel(); long position = 0; fromChannel.transferTo(position,toChannel.size(),toChannel); fromChannel.close(); toChannel.close(); }
selector
Selector selector = Selector.open(); SelectableChannel channel = null;// TODO channel.configureBlocking(false);//非阻塞模式 //channel注册selector,第二个参数是intreast事件,多个intreast事件可以用“|” // int intreastSetP = SelectionKey.OP_ACCEPT | SelectionKey.OP_READ; SelectionKey selectionKey1 = channel.register(selector, SelectionKey.OP_READ); int intreastSet = selectionKey1.interestOps(); int readySet = selectionKey1.readyOps(); //添加附加对象 selectionKey1.attach(new Object()); //取出附加对象 selectionKey1.attachment(); //选取通道 selector.select();//block when at least a ready channel that you regist selector.select(1000);//timeout selector.selectNow();//return immediately Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); if (selectionKey.isAcceptable()) { // 这两个含义不太清楚 } else if (selectionKey.isConnectable()) { // 这两个含义不太清楚 } else if (selectionKey.isReadable()) { // a channel is ready for reading } else if (selectionKey.isWritable()) { // a channel is ready for writing } iterator.remove(); SelectableChannel selectableChannel = selectionKey.channel(); }whole demo
public void selectTest() throws IOException { Selector selector = Selector.open(); SelectableChannel channel = null; channel.register(selector, SelectionKey.OP_READ); while (true) { int readyChannels = selector.select(); if (readyChannels == 0) continue; Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> iteratror = selectedKeys.iterator(); while (iteratror.hasNext()) { SelectionKey selectionKey = iteratror.next(); if (selectionKey.isReadable()) { // TODO } iteratror.remove(); } } }
pipe
//两个线程的单向数据连接 public void pipePractice() throws IOException { Pipe pipe = Pipe.open(); Pipe.SinkChannel sinkChannel = pipe.sink(); writeToSonk(); Pipe.SourceChannel sourceChannel = pipe.source(); readFromSource(); } private void readFromSource() { // TODO } private void writeToSonk() { // TODO }