Java NIO - 零拷贝

NIO 零拷贝
使用传统的 IO 方法传递一个大文件

使用 NIO 零拷贝方式传递 (transferTo) 一个大文件

看看两种传递方式耗时时间分别是多少

传统 IO 方法
服务端代码

public class OldServer {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(1212);
            System.out.println("服务端启动已启动......");
            while (true) {
                // 等待连接
                Socket socket = serverSocket.accept();
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // 接收消息
                        try (InputStream inputStream = socket.getInputStream()){
                            byte[] result = new byte[1024];
                            while (true) {
                                int read = inputStream.read(result);
                                if (read == -1) {
                                    break;
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

客户端代码

public class OldClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("localhost", 1212);
        OutputStream outputStream = socket.getOutputStream();
        // 文件大小为300MB
        File file = new File("D:\\电子书\\深入理解Apache Dubbo与实战.pdf");
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        long total = 0;
        long startTime = System.currentTimeMillis();
        while (true) {
            long readCount = fileInputStream.read(buffer);
            if (readCount == -1) {
                break;
            }
            total += readCount;
            outputStream.write(buffer);
        }
        outputStream.flush();
        System.out.println("发送总字节数: " + total + ", 耗时: " + (System.currentTimeMillis() - startTime));
        fileInputStream.close();

        socket.close();
    }
}

NIO 零拷贝
服务端代码

public class NewIOServer {
    public static void main(String[] args) throws Exception {

        InetSocketAddress address = new InetSocketAddress(1313);
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        ServerSocket serverSocket = serverSocketChannel.socket();
        serverSocket.bind(address);
        System.out.println("服务端启动已启动......");
        //创建buffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
        while (true) {
            SocketChannel socketChannel = serverSocketChannel.accept();
            int readcount = 0;
            while (-1 != readcount) {
                try {
                    readcount = socketChannel.read(byteBuffer);
                }catch (Exception ex) {
                   // ex.printStackTrace();
                    break;
                }
                //
                byteBuffer.rewind(); //倒带 position = 0 mark 作废
            }
        }
    }
}

客户端代码

public class NewIOClient {
    public static void main(String[] args) throws Exception {

        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(new InetSocketAddress("localhost", 1313));
        // 文件大小为300MB
        String filename = "D:\\电子书\\深入理解Apache Dubbo与实战.pdf";
        //得到一个文件channel
        FileChannel fileChannel = new FileInputStream(filename).getChannel();
        //准备发送
        long startTime = System.currentTimeMillis();
        // 在linux下,一次transferTo 就可以完成传输
        //transferTo 底层使用到零拷贝
        // long transferCount = fileChannel.transferTo(0, fileChannel.size(), socketChannel);

        //在windows下,一次ransferTo 只能发送8m , 就需要分段传输文件
        long total = 0;
        long position = 0; // 读取位置
        while (true) {
            long transferCount = fileChannel.transferTo(position, fileChannel.size(), socketChannel);
            if (transferCount > 0) {
                position = position + transferCount;
                total = total + transferCount;
            } else {
                break;
            }
        }

        System.out.println("发送的总的字节数 =" + total + " 耗时:" + (System.currentTimeMillis() - startTime));
        //关闭
        fileChannel.close();

    }
}

————————————————
原文作者:LZC
转自链接:https://learnku.com/articles/46012
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值