美文网首页
NIO复制文件的三种方式对比

NIO复制文件的三种方式对比

作者: 多彩海洋 | 来源:发表于2019-10-15 22:24 被阅读0次

方式一:利用通道完成文件的复制(非直接缓冲区)

@Test
public void copyFirst(){
        
        // 为了比较效率,记录程序执行时间
        long startTime = System.currentTimeMillis();  // 开始时间
        
        // 1 声明输入输出流
        FileInputStream fis = null;
        FileOutputStream fos = null;
        // 2 声明通道
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        
        try {
            // 3 创建输入输出流
            fis = new FileInputStream("C:/Java/NIO.pdf");
            fos = new FileOutputStream("C:/Java/newNIO.pdf");
            
            // 4 获取通道
            inChannel = fis.getChannel();
            outChannel = fos.getChannel();
            
            // 5 分配指定大小的缓冲区
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            
            // 6 将通道中的数据存入缓存区中
            while(inChannel.read(buffer) != -1){
                buffer.flip();  // 切换到读取数据的模式
                // 7 将缓存区中的数据写入通道中
                outChannel.write(buffer);
                buffer.clear();  // 清空缓存区
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(outChannel != null){
                try{
                    outChannel.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
            if(inChannel != null){
                try{
                    inChannel.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
            if(fos != null){
                try{
                    fos.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
            if(fis != null){
                try{
                    fis.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
        
        // 记录结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("用通道完成文件的复制(非直接缓冲区)耗时为" + (endTime - startTime) + "秒");
    }

运行三次的时间分别为:
用通道完成文件的复制(非直接缓冲区)耗时为1220秒
用通道完成文件的复制(非直接缓冲区)耗时为1213秒
用通道完成文件的复制(非直接缓冲区)耗时为1226秒

第二种方法:使用直接缓冲区完成文件的复制(内存映射文件)

@Test
public void copySecond(){
        
        long startTime = System.currentTimeMillis();
        
        FileChannel inChannel = null;
        FileChannel outChannel = null;      
        
        try {
            // 获取通道
            inChannel = FileChannel.open(Paths.get("C:/Java/NIO.pdf"), StandardOpenOption.READ);
            outChannel = FileChannel.open(Paths.get("C:/Java/newNIO.pdf"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
            
            // 设置内存映射文件
            MappedByteBuffer imb = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
            MappedByteBuffer omb = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
            
            // 直接对缓冲区进行数据的读写操作
            byte[] data = new byte[imb.limit()];
            imb.get(data);
            omb.put(data);
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(inChannel != null){
                try {
                    inChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outChannel != null){
                try {
                    outChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
        // 记录结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("使用直接缓冲区完成文件的复制(内存映射文件)耗时为" + (endTime - startTime) + "秒");
    }

运行三次的时间分别为:
使用直接缓冲区完成文件的复制(内存映射文件)耗时为107秒
使用直接缓冲区完成文件的复制(内存映射文件)耗时为112秒
使用直接缓冲区完成文件的复制(内存映射文件)耗时为107秒

方式三:通道之间的数据传输(直接缓存区)

@Test
public void copyThird(){
        
        long startTime = System.currentTimeMillis();
        
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        
        try {
            inChannel = FileChannel.open(Paths.get("C:/Java/NIO.pdf"), StandardOpenOption.READ);
            outChannel = FileChannel.open(Paths.get("C:/Java/newNIO.pdf"), StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
            inChannel.transferTo(0, inChannel.size(), outChannel);
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(inChannel != null){
                try {
                    inChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(outChannel != null){
                try {
                    outChannel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
        long endTime = System.currentTimeMillis();
        System.out.println("通道之间的数据传输(直接缓存区)耗时为" + (endTime - startTime) + "秒");
    }

运行三次的时间分别为:
通道之间的数据传输(直接缓存区)耗时为73秒
通道之间的数据传输(直接缓存区)耗时为64秒
通道之间的数据传输(直接缓存区)耗时为68秒

相关文章

网友评论

      本文标题:NIO复制文件的三种方式对比

      本文链接:https://www.haomeiwen.com/subject/gcmemctx.html