NIO简单应用

NIO简单应用

使用FileChannel完成文件复制

public class FileNIOCopyDemo {
    public static void main(String[] args) {
        nioCopyResourceFile();
    }

    /**
     * 复制两个资源目录下的文件
     */
    private static void nioCopyResourceFile() {
        String sourcePath = NioDemoConfig.sourcePath;
        String destPath = NioDemoConfig.destPath;
        nioCopyFile(sourcePath, destPath);
    }

    private static void nioCopyFile(String sourcePath, String destPath) {
        File srcFile = new File(sourcePath);
        File destFile = new File(destPath);
        try {
            if (!destFile.exists()) {
                destFile.createNewFile();
            }
            long startTime = System.currentTimeMillis();
            FileInputStream fis = null;
            FileOutputStream  fos = null;
            FileChannel inChannel = null;
            FileChannel outChannel = null;

            try {
                fis = new FileInputStream(srcFile);
                fos = new FileOutputStream(destFile);
                inChannel = fis.getChannel();
                outChannel = fos.getChannel();

                ByteBuffer buffer = ByteBuffer.allocate(1024);
                int length = 0;
                int outlength = 0;
                //从读通道读取数据到buffer
                while ((length = inChannel.read(buffer)) != -1) {
                    //切换buffer至读模式
                    buffer.flip();
                    //将buffer内容写入输出channel
                    while ((outlength = outChannel.write(buffer)) != 0) {
                        System.out.println("写入的字节数: " + outlength);
                    }
                    //切换buffer为写模式
                    buffer.clear();
                }
                //强制刷新到磁盘
                outChannel.force(true);
            } finally {
                closeUtil(outChannel);
                closeUtil(inChannel);
                closeUtil(fos);
                closeUtil(fis);
                Long endTime = System.currentTimeMillis();
                System.out.println("复制花费毫秒数: " + (endTime - startTime));
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void closeUtil(Closeable item) {
        if (item != null) {
            try {
                item.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }


}

使用SocketChannel发送文件

客户端发送
public class NioSendClient {
    private Charset charset = Charset.forName("UTF-8");

    public static void main(String[] args) {
        NioSendClient client = new NioSendClient();//启动客户端连接
        client.sendFile();//传输文件

    }

    /**
     * 向服务器传输文件
     */
    private void sendFile() {
        try {
            //获取源文件、目的文件路径
            String srcPath = NioDemoConfig.sourcePath;
            String destPath = NioDemoConfig.destPath;
            //获取源文件File对象
            File srcFile = new File(srcPath);
            if (!srcFile.exists()) {
                System.out.println("文件不存在");
                return;
            }
            //获取源文件流
            FileInputStream fileInputStream = new FileInputStream(srcFile);
            //获取源文件通道
            FileChannel fileChannel = fileInputStream.getChannel();
            //获取Socket通道
            SocketChannel socketChannel = SocketChannel.open();
            //连接服务端
            socketChannel.connect(new InetSocketAddress(NioDemoConfig.SOCKET_SERVER_IP, NioDemoConfig.SOCKET_SERVER_PORT));
            //设置channel为非阻塞
            socketChannel.configureBlocking(false);
            //自旋,等待连接完成
            while (!socketChannel.finishConnect()) {
                //不断自旋、等待,或者做一些其他操作
            }
            System.out.println("Client成功连接服务器端");

            //发送文件名称
            ByteBuffer fileNameByteBuffer = charset.encode(destPath);
            socketChannel.write(fileNameByteBuffer);

            //发送文件长度
            ByteBuffer buffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);
            buffer.putLong(srcFile.length());
            buffer.flip();
            socketChannel.write(buffer);
            buffer.clear();
            //发送文件内容
            System.out.println("开始传输文件");
            int length = 0;
            long progress = 0;
            while ((length = fileChannel.read(buffer)) > 0) {
                buffer.flip();
                socketChannel.write(buffer);
                buffer.clear();
                progress += length;
                System.out.println("| " + (100 * progress / srcFile.length()) + "% |");
            }

            //判断文件传输结束,发送结束符至对端
            if (length == -1) {
                closeUtil(fileChannel);
                //在SocketChannel传输通道关闭前,尽量发送一个输出结果标志到对端
                socketChannel.shutdownOutput();
                closeUtil(socketChannel);
            }
            System.out.println("====== 文件传输成功 =======");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void closeUtil(Closeable item) {
        if (item != null) {
            try {
                item.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

使用DatagramChannel数据报通道发送数据

客户端
public class UDPClient {
    public static void main(String[] args) throws IOException {
        new UDPClient().send();
    }

    public void send() throws IOException {
        //获取DatagramChannel数据报通道
        DatagramChannel channel = DatagramChannel.open();
        //设置为非阻塞
        channel.configureBlocking(false);
        //创建ByteBuffer
        ByteBuffer buffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);
        //扫描输入
        Scanner scanner = new Scanner(System.in);
        //遍历扫描到的内容,发送数据
        while (scanner.hasNext()) {
            String next = scanner.next();
            buffer.put(next.getBytes());
            channel.send(buffer, new InetSocketAddress(NioDemoConfig.SOCKET_SERVER_IP, NioDemoConfig.SOCKET_SERVER_PORT));
            buffer.clear();
        }
        //关闭数据报通道
        channel.close();

    }
}
服务端
public class UDPServer {
    public static void main(String[] args) throws IOException {
        new UDPServer().receive();
    }

    public void receive() throws IOException {
        //获取数据报通道
        DatagramChannel channel = DatagramChannel.open();
        //设置为非阻塞
        channel.configureBlocking(false);
        //绑定监听地址
        channel.socket().bind(new InetSocketAddress(NioDemoConfig.SOCKET_SERVER_IP, NioDemoConfig.SOCKET_SERVER_PORT));
        //开启一个通道选择器
        Selector selector = Selector.open();
        //将通道注册到选择器
        channel.register(selector, SelectionKey.OP_READ);
        //通过选择器,查询IO事件
        while (selector.select() > 0) {
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            ByteBuffer buffer = ByteBuffer.allocate(NioDemoConfig.SEND_BUFFER_SIZE);

            //迭代IO事件
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                //可读事件,有事件到来
                if (selectionKey.isReadable()) {
                    //读取数据报通道的数据
                    SocketAddress client = channel.receive(buffer);
                    buffer.flip();
                    System.out.println(new String(buffer.array(), 0, buffer.limit()));
                    buffer.clear();
                }
            }
            iterator.remove();
        }

    }
}

参考资料:《Netty、Redis、Zookeeper高并发实战》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值