Channel

    public static void write(String path) throws Exception {
        RandomAccessFile aFile = new RandomAccessFile(path, "rw");
        FileChannel channel = aFile.getChannel();
        ByteBuffer buf = ByteBuffer.allocate(100);
        buf.put("i will come back!!".getBytes());
        buf.flip();
        while(buf.hasRemaining()) {
            channel.write(buf);
        }
        channel.close();
        aFile.close();
        System.out.println("end");
        if(buf.hasRemaining())
        System.out.println(buf.get());
        System.out.println(buf.get());
        System.out.println(buf.get());
    }

    public static void read(String path) throws Exception {
        RandomAccessFile aFile = new RandomAccessFile(path, "rw");
        FileChannel channel = aFile.getChannel();

        ByteBuffer buf = ByteBuffer.allocate(10);
        int byteRead = channel.read(buf);
        while (byteRead != -1) {
            System.out.println("读取了:" + byteRead);
            buf.flip();
            while (buf.hasRemaining()) {
                System.out.print((char) buf.get());
            }
            buf.clear();
            byteRead = channel.read(buf);
        }
        channel.close();
        aFile.close();
        System.out.println("end");
    }
    public static void writeTOFile() {
        
    }
}
        InetSocketAddress address = new InetSocketAddress("www.baidu.com",80);
//        SocketChannel socketChanne = SocketChannel.open(address);
        SocketChannel socketChanne2 = SocketChannel.open();
        socketChanne2.connect(address);
        socketChanne2.configureBlocking(false);
// udp 没有服务端 ,双方边监听边发送

ByteBuffer

package org.child2;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import junit.framework.TestCase;
/**
 * Unit test for simple App.
 */
public class AppTest extends TestCase {
    public void testApp() {
        ByteBuffer buffer = ByteBuffer.allocate(3);
        buffer.rewind(); //重复读的时候使用
        buffer.clear();  //初始化
        buffer.compact(); //读一半,想写了,清除读过的,把没读的移到前边
        buffer.slice();// 缓冲区分片,可影响原数据
        buffer.asReadOnlyBuffer();//只读缓冲区分片,原数据影响分片
        buffer.allocateDirect(1024); // 直接用系统内存,速度快,allocate:系统分配后,获取值赋值给jvm,所以速度慢
        buffer.mark(); //标记
        buffer.reset();// 恢复
        buffer.remaining(); // 是否有剩余:limit-position
        buffer.hasRemaining();// 同上
        // MappedByteBuffer mbb = fc.map(FileChannel.MapMode.REWA_WRITE,0,1024)   内存映射文件IO,只读到的内容映射到内存
        
        buffer.put((byte)49);
        buffer.put((byte)50);
//        buffer.rewind();
        buffer.clear();
        buffer.put((byte)51);
        buffer.put((byte)51);
        buffer.put((byte)51);
        buffer.flip();
        System.out.println((char)buffer.get());
        System.out.println((char)buffer.get());
        System.out.println((char)buffer.get());

    
    }
}

Selector

  • 可以被复用的channel:SocketChannel,继承了Selectable,FileChannel没有继承,不能被复用
  • 一个通道可以被注册到多个select,但,对于选择器只能注册一次

通道注册

channel.register(selector,ops)
ops:read,write,connect,accept   可通过 “|” 选择多个

状态查询

selector.select()--->选择键集合SelectionKey
package org.child2;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class SelectorDemo {
    public static void main(String[] args) throws Exception {
        Selector selector = Selector.open();
        
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(9000));    
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        
        while(selector.select()>0) {
            Set<SelectionKey> selectedKeys = selector.selectedKeys(); // 获取所有操作
            Iterator<SelectionKey> iterator = selectedKeys.iterator();
            while(iterator.hasNext()) { // 处理操作
                SelectionKey next = iterator.next();
                if(next.isAcceptable()) {// 连接事件
                    SocketChannel accept = serverSocketChannel.accept(); // 获取通道
                    accept.configureBlocking(false);
                    accept.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE);
                }else if(next.isConnectable()) {
                    
                }else if(next.isWritable()) {
                    SocketChannel channel = (SocketChannel)next.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int length=0;
                    while((length = channel.read(buffer))>0) {
                        buffer.flip();
                        System.out.println("received:"+channel.socket().getRemoteSocketAddress()+new String(buffer.array()));
                        buffer.clear();
                    }
                }else if(next.isReadable()) {
                    
                }
                iterator.remove();
            }
            
            Thread.sleep(2000);
        }
    }
}

Pipe 管道

package org.child2;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Pipe;
import java.nio.channels.Pipe.SinkChannel;
import java.nio.channels.Pipe.SourceChannel;

public class PipeDemo {
    public static void main(String[] args) throws Exception {
        // 获取管道
        Pipe pipe =Pipe.open();
        // 获取sink
        SinkChannel sink = pipe.sink();
        // 创建缓冲区
        ByteBuffer allocate = ByteBuffer.allocate(1024);
        allocate.put("dzf".getBytes());
        allocate.flip();
        // 写入
        sink.write(allocate);
        // 获取source
        SourceChannel source = pipe.source();
        
        // 创建缓冲区
        ByteBuffer allocate2 = ByteBuffer.allocate(1024);
        source.read(allocate2);
        System.out.println(new String(allocate2.array()));
        // 关闭
        sink.close();
        source.close();
    }
}

标签: none

评论已关闭