zoukankan      html  css  js  c++  java
  • java nio之channel

      一、通道(Channel):由 java.nio.channels 包定义的。Channel 表示 IO 源与目标打开的连接。Channel 类似于传统的“流”。只不过 Channel本身不能直接访问数据,Channel 只能与Buffer 进行交互。

      二、Channel重要实现

    • FileChannel:操作文件的读写
    • SocketChannel:通过TCP读写网络数据
    • ServerSocketChannel:监听TCP连接,你能利用它创建一个最简单的Web服务器
    • DatagramChannel:通过UDP读写网络数据

      三、FileChannel 的文件读写

      1)利用FileChannel 本身提供的transferTo进行数据的读写。

    package com.troy.nio.application;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.nio.channels.FileChannel;
    
    public class Channel {
    
        public static void main(String[] args) throws Exception {
            //读取文件
            FileInputStream fileInputStream = new FileInputStream("d:/t.txt");
            //写出文件
            FileOutputStream fileOutputStream = new FileOutputStream("d:/e.txt");
            //获取读取通道
            FileChannel inChannel = fileInputStream.getChannel();
            //获取写入通道
            FileChannel outChannel = fileOutputStream.getChannel();
            //完成数据的写入
            inChannel.transferTo(0,inChannel.size(),outChannel);
        }
    }

      2)利用FileChannel 提供的读写方法

    package com.troy.nio.application;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;
    
    public class Channel {
    
        public static void main(String[] args) throws Exception {
            //读取文件
            FileInputStream fileInputStream = new FileInputStream("d:/t.txt");
            //写出文件
            FileOutputStream fileOutputStream = new FileOutputStream("d:/e.txt");
            //获取读取通道
            FileChannel inChannel = fileInputStream.getChannel();
            //获取写入通道
            FileChannel outChannel = fileOutputStream.getChannel();
            //缓存
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            //读取数据
            while (inChannel.read(byteBuffer) != -1) {
                //转换成可读写
                byteBuffer.flip();
                System.out.println(new String(byteBuffer.array(),"GBK").trim());
                //写出数据,清楚缓存
                outChannel.write(byteBuffer);
                byteBuffer.clear();
            }
        }
    }

      四、SocketChannel和ServerSocketChannel在同时使用时,都是tcp协议进行传输的,在使用上面比较服务具体的协议控制

      具体的应用可以参考:http://www.cnblogs.com/ll409546297/p/7929646.html

      五、DatagramChannel的方式

      1)客户端

    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.DatagramChannel;
    
    public class UDPClient {
    
        public static void main(String[] args) throws Exception {
    
            //获取UDP通道
            DatagramChannel datagramChannel = DatagramChannel.open();
            //设置非阻塞
            datagramChannel.configureBlocking(false);
            //发送数据
            datagramChannel.send(ByteBuffer.wrap("hello server!".getBytes()),new InetSocketAddress("localhost",9000));
        }
    }

      2)服务端的2中写法,阻塞和非阻塞

      1、阻塞

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.DatagramChannel;
    
    public class UDPServer {
    
        //UDP通道
        private static DatagramChannel datagramChannel;
    
        public static void main(String[] args) throws Exception {
            serverInit();
            listen();
        }
    
        //初始化
        private static void serverInit() throws IOException {
            //获取UDP通道
            datagramChannel = DatagramChannel.open();
            //设置接收端口
            datagramChannel.socket().bind(new InetSocketAddress(9000));
        }
    
        //监听
        private static void listen() throws IOException {
            while (true) {
                //接收的长度
                ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                //这里会阻塞
                datagramChannel.receive(byteBuffer);
                byteBuffer.flip();
                System.out.println(new String(byteBuffer.array()).trim());
            }
        }
    }

      2、非阻塞,利用selector来进行数据选择

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.DatagramChannel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.util.Iterator;
    
    public class UDPServer {
    
        //选择器
        private static Selector selector;
        //UDP通道
        private static DatagramChannel datagramChannel;
    
        public static void main(String[] args) throws Exception {
            serverInit();
            listen();
        }
    
        //初始化
        private static void serverInit() throws IOException {
            //获取选择器
            selector = Selector.open();
            //获取UDP通道
            datagramChannel = DatagramChannel.open();
            //设置非阻塞
            datagramChannel.configureBlocking(false);
            //设置接收端口
            datagramChannel.socket().bind(new InetSocketAddress(9000));
            //注册
            datagramChannel.register(selector, SelectionKey.OP_READ);
        }
    
        //监听
        private static void listen() throws IOException {
            while (true) {
                selector.select();
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey selectionKey = iterator.next();
                    if (selectionKey.isReadable()) {
                        //接收的长度
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                        //这里不会阻塞
                        datagramChannel.receive(byteBuffer);
                        byteBuffer.flip();
                        System.out.println(new String(byteBuffer.array()).trim());
                    }
                }
            }
        }
    }

      六、基本上channel的实现用法就这些了,但是里面会涉及到很多细节的用法,这个需要自己进一步研究

  • 相关阅读:
    例如找出令人信服的权威C++中间malloc与new
    nRF905
    POJ 3280 间隔DP
    SharePoint管理中心来配置资源限制(大名单)
    C#值传递和按引用传递
    UVA 810
    hdu 4870 Rating(可能性DP&amp;高数消除)
    【Espruino】NO.06 关键是你的仆人(继续)
    Struts2_1_struts2建立一个执行环境
    kendoui仪表板和直方图 演示样本
  • 原文地址:https://www.cnblogs.com/ll409546297/p/7941217.html
Copyright © 2011-2022 走看看