博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java NIO
阅读量:7305 次
发布时间:2019-06-30

本文共 5974 字,大约阅读时间需要 19 分钟。

hot3.png

demo

public static void method1(){        RandomAccessFile aFile = null;        try{            aFile = new RandomAccessFile("src/nio.txt","rw");            FileChannel fileChannel = aFile.getChannel();            ByteBuffer buf = ByteBuffer.allocate(1024);             int bytesRead = fileChannel.read(buf);            System.out.println(bytesRead);             while(bytesRead != -1)            {                buf.flip();                while(buf.hasRemaining())                {                    System.out.print((char)buf.get());                }                 buf.compact();                bytesRead = fileChannel.read(buf);            }        }catch (IOException e){            e.printStackTrace();        }finally{            try{                if(aFile != null){                    aFile.close();                }            }catch (IOException e){                e.printStackTrace();            }        }    }

分析

从案例2中可以总结出使用Buffer一般遵循下面几个步骤:

  • 分配空间(ByteBuffer buf = ByteBuffer.allocate(1024); 还有一种allocateDirector后面再陈述)
  • 写入数据到Buffer(int bytesRead = fileChannel.read(buf);)
  • 调用filp()方法( buf.flip();)
  • 从Buffer中读取数据(System.out.print((char)buf.get());)
  • 调用clear()方法或者compact()方法

Buffer顾名思义:缓冲区,实际上是一个容器,一个连续数组。Channel提供从文件、网络读取数据的渠道,但是读写的数据都必须经过Buffer。如下图:

输入图片说明

向Buffer中写数据:

  • 从Channel写到Buffer (fileChannel.read(buf))
  • 通过Buffer的put()方法 (buf.put(…))

从Buffer中读取数据:

  • 从Buffer读取到Channel (channel.write(buf))
  • 使用get()方法从Buffer中读取数据 (buf.get())

可以把Buffer简单地理解为一组基本数据类型的元素列表,它通过几个变量来保存这个数据的当前位置状态:capacity, position, limit, mark:

Selector简介

服务端

public class ServerSocketChannelTest {    private int size = 1024;    private ServerSocketChannel socketChannel;    private ByteBuffer byteBuffer;    private Selector selector;    private final int port = 8998;    private int remoteClientNum=0;    public ServerSocketChannelTest() {        try {            initChannel();        } catch (Exception e) {            e.printStackTrace();            System.exit(-1);        }    }    public void initChannel() throws Exception {        socketChannel = ServerSocketChannel.open();        socketChannel.configureBlocking(false);        socketChannel.bind(new InetSocketAddress(port));        System.out.println("listener on port:" + port);        selector = Selector.open();        socketChannel.register(selector, SelectionKey.OP_ACCEPT);        byteBuffer = ByteBuffer.allocateDirect(size);        byteBuffer.order(ByteOrder.BIG_ENDIAN);    }    private void listener() throws Exception {        while (true) {            int n = selector.select();            if (n == 0) {                continue;            }            Iterator
ite = selector.selectedKeys().iterator(); while (ite.hasNext()) { SelectionKey key = ite.next(); //a connection was accepted by a ServerSocketChannel. if (key.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel) key.channel(); SocketChannel channel = server.accept(); registerChannel(selector, channel, SelectionKey.OP_READ); remoteClientNum++; System.out.println("online client num="+remoteClientNum); replyClient(channel); } //a channel is ready for reading if (key.isReadable()) { readDataFromSocket(key); } ite.remove();//must } } } protected void readDataFromSocket(SelectionKey key) throws Exception { SocketChannel socketChannel = (SocketChannel) key.channel(); int count; byteBuffer.clear(); while ((count = socketChannel.read(byteBuffer)) > 0) { byteBuffer.flip(); // Make buffer readable // Send the data; don't assume it goes all at once while (byteBuffer.hasRemaining()) { socketChannel.write(byteBuffer); } byteBuffer.clear(); // Empty buffer } if (count < 0) { socketChannel.close(); } } private void replyClient(SocketChannel channel) throws IOException { byteBuffer.clear(); byteBuffer.put("hello client!\r\n".getBytes()); byteBuffer.flip(); channel.write(byteBuffer); } private void registerChannel(Selector selector, SocketChannel channel, int ops) throws Exception { if (channel == null) { return; } channel.configureBlocking(false); channel.register(selector, ops); } public static void main(String[] args) { try { new ServerSocketChannelTest().listener(); } catch (Exception e) { e.printStackTrace(); } }}

客户端代码:

public class SocketChannelTest {    private int size = 1024;    private ByteBuffer byteBuffer;    private SocketChannel socketChannel;    public void connectServer() throws IOException {        socketChannel = SocketChannel.open();        socketChannel.connect(new InetSocketAddress("127.0.0.1", 8998));        byteBuffer = ByteBuffer.allocate(size);        byteBuffer.order(ByteOrder.BIG_ENDIAN);        receive();    }    private void receive() throws IOException {        while (true) {            int count;            byteBuffer.clear();            while ((count = socketChannel.read(byteBuffer)) > 0) {                byteBuffer.flip();                while (byteBuffer.hasRemaining()) {                    System.out.print((char) byteBuffer.get());                }                //send("send data to server\r\n".getBytes());                byteBuffer.clear();            }        }    }    private void send(byte[] data) throws IOException {        byteBuffer.clear();        byteBuffer.put(data);        byteBuffer.flip();        socketChannel.write(byteBuffer);    }    public static void main(String[] args) throws IOException {        new SocketChannelTest().connectServer();    }}

链接

转载于:https://my.oschina.net/u/3421984/blog/1793568

你可能感兴趣的文章
在隧道上运行IS-IS 和is-is验证
查看>>
2017年技术新目标
查看>>
linuxt系统磁盘分区知识
查看>>
我的友情链接
查看>>
二叉树中和为某一值的路径
查看>>
nginx日志切割shell
查看>>
帧中继配置实例
查看>>
保留符合要求的N个条目,括号匹配
查看>>
执行力
查看>>
iframe框架中函数的相互调用
查看>>
我的友情链接
查看>>
使用TortoiseGit,设置ssh方式连接git仓库。
查看>>
Netcat 命令——网络工具中的瑞士军刀
查看>>
elasticsearch 设置使用磁盘上限百分比
查看>>
javax.net.ssl.SSLKeyException: RSA premaster secre
查看>>
域名汇总
查看>>
微信小程序 文档地址备注
查看>>
函数式对象之方法重载
查看>>
动视暴雪裁员:《魔兽世界》黄金时代一去不复返
查看>>
python 中set模块的用法
查看>>