经过一组简单的测试发现JAVA NIO提供的文件内存映射方法实现文件拷贝速度最快,不管是大文件还是小文件,特别是大文件的拷贝速度比普通方法提高20倍,唯一有个前提就是内存需要足够大,否则文件映射肯定失败(当然可以通过分割文件,部分映射的方法避免,但就比较麻烦了);其次NIO提供的文件管道传输速度也比较好,如果没法做文件内存映射,推荐这种拷贝方法;另外,Buffer的大小,对于读写速度还是有影响的,基本就是Buffer越大读写越快(有个疑问就是Buffer.allocateDirec()效率提高不明显);最后,总体看来NIO的效率比老IO高,不管使用哪种方式,老IO使用流读写只能一个字节一个字节的抠,NIO使用块的方式读写还是相对比较快,所以没有特别需求的情况下,推荐使用NIO,目前NIO基本能覆盖老IO的所有功能(当然NIO还提供N多新功能)。

  • 测试环境

1
2
3
4
5
6
7
8
9
Eclipse(Juno) JVM(Sun JDK1.7) 参数:
-Xms1536m
-Xmx1536m
-Xverify:none -XX:+UseParallelGC
-XX:PermSize=128M
-XX:MaxPermSize=128M
OS参数:
Win7 64Bit + 4GB
物理磁盘空间充足

  • 测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class FileCopy {
    private static final int BUFFER_SIZE_1024 = 1024;
    private static final int BUFFER_SIZE_4096 = 4096;
    private static final int BUFFER_SIZE_10240 = 10240;
        
    private static final String FROM_FILE_42MB = "G:/from_42MB.rar";
    private static final String FROM_FILE_1GB = "G:/from_350MB.rar";
        
    private static int BUFFER_SIZE = BUFFER_SIZE_1024;
    private static String FROM_FILE = FROM_FILE_42MB;
    /**
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        System.out.println("File :" + FROM_FILE + " ---- Buffer Size : " + BUFFER_SIZE + "--------------");
        testFileCopy();
            
        BUFFER_SIZE = BUFFER_SIZE_4096;
        System.out.println("File :" + FROM_FILE + " ---- Buffer Size : " + BUFFER_SIZE + "--------------");
        testFileCopy();
            
        BUFFER_SIZE = BUFFER_SIZE_10240;
        System.out.println("File :" + FROM_FILE + " ---- Buffer Size : " + BUFFER_SIZE + "--------------");
        testFileCopy();
            
        BUFFER_SIZE = BUFFER_SIZE_1024;
        FROM_FILE = FROM_FILE_1GB;
        System.out.println("File :" + FROM_FILE + " ---- Buffer Size : " + BUFFER_SIZE + "--------------");
        testFileCopy();
            
        BUFFER_SIZE = BUFFER_SIZE_4096;
        FROM_FILE = FROM_FILE_1GB;
        System.out.println("File :" + FROM_FILE + " ---- Buffer Size : " + BUFFER_SIZE + "--------------");
        testFileCopy();
            
        BUFFER_SIZE = BUFFER_SIZE_10240;
        FROM_FILE = FROM_FILE_1GB;
        System.out.println("File :" + FROM_FILE + " ---- Buffer Size : " + BUFFER_SIZE + "--------------");
        testFileCopy();
            
    }
    private static void testFileCopy() throws FileNotFoundException,
            IOException {
        coypByMbb();
        copyByNioTransferFrom();
        copyByNioTransferTo();
        coypByBufferRead();
        coypByFastBufferRead();           
        coypByStream();//Old IO style
    }
    /**
     * 使用FileChannel.transferFrom()实现
     * @throws FileNotFoundException
     * @throws IOException
     */
    private static void copyByNioTransferFrom() throws FileNotFoundException,
            IOException {
        long startTime = System.currentTimeMillis();
        RandomAccessFile fromFile = new RandomAccessFile(FROM_FILE, "rw");
        FileChannel fromChannel = fromFile.getChannel();
        RandomAccessFile toFile = new RandomAccessFile("G:/to1.rar""rw");
        FileChannel toChannel = toFile.getChannel();
        long position = 0;
        long count = fromChannel.size();
        toChannel.transferFrom(fromChannel, position, count);
        long endTime = System.currentTimeMillis();
        System.out.println("copyByNioTransferFrom time consumed(buffer size no effect) : "
                + (endTime - startTime));
    }
    /**
     * 使用FileChannel.transferTo()实现
     * @throws FileNotFoundException
     * @throws IOException
     */
    private static void copyByNioTransferTo() throws FileNotFoundException,
            IOException {
        long startTime = System.currentTimeMillis();
        RandomAccessFile fromFile = new RandomAccessFile(FROM_FILE, "rw");
        FileChannel fromChannel = fromFile.getChannel();
        RandomAccessFile toFile = new RandomAccessFile("G:/to2.rar""rw");
        FileChannel toChannel = toFile.getChannel();
        long position = 0;
        long count = fromChannel.size();
        fromChannel.transferTo(position, count, toChannel);
        long endTime = System.currentTimeMillis();
        System.out.println("copyByNioTransferTo time consumed(buffer size no effect) : "
                + (endTime - startTime));
    }
    /**
     * 使用Channel, Buffer简单读写实现
     * @throws IOException
     */
    private static void coypByBufferRead() throws IOException {
        long startTime = System.currentTimeMillis();
        FileInputStream fin = new FileInputStream(FROM_FILE);
        FileOutputStream fout = new FileOutputStream("G:/to3.rar");
        FileChannel fcin = fin.getChannel();
        FileChannel fcout = fout.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
        while (true) {
            buffer.clear();
            int r = fcin.read(buffer);
            if (r == -1) {
                break;
            }
            buffer.flip();
            fcout.write(buffer);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("coypByBufferRead time consumed(buffer size take effect) : "
                + (endTime - startTime));
    }
    /**
     * 使用连续内存的Buffer实现
     * @throws IOException
     */
    private static void coypByFastBufferRead() throws IOException {
        long startTime = System.currentTimeMillis();
        FileInputStream fin = new FileInputStream(FROM_FILE);
        FileOutputStream fout = new FileOutputStream("G:/to4.rar");
        FileChannel fcin = fin.getChannel();
        FileChannel fcout = fout.getChannel();
        ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
        while (true) {
            buffer.clear();
            int r = fcin.read(buffer);
            if (r == -1) {
                break;
            }
            buffer.flip();
            fcout.write(buffer);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("coypByFastBufferRead time consumed(buffer size take effect) : "
                + (endTime - startTime));
    }
    /**
     * 使用文件内存映射实现
     * @throws IOException
     */
    private static void coypByMbb() throws IOException {
        long startTime = System.currentTimeMillis();
        FileInputStream fin = new FileInputStream(FROM_FILE);
        RandomAccessFile fout = new RandomAccessFile("G:/to5.rar""rw");
        FileChannel fcin = fin.getChannel();
        FileChannel fcout = fout.getChannel();
        MappedByteBuffer mbbi = fcin.map(FileChannel.MapMode.READ_ONLY, 0,
                fcin.size());
        MappedByteBuffer mbbo = fcout.map(FileChannel.MapMode.READ_WRITE, 0,
                fcin.size());
        mbbo.put(mbbi);
        mbbi.clear();
        mbbo.clear();
        long endTime = System.currentTimeMillis();
        System.out
                .println("coypByMbb time consumed(buffer size no effect) : " + (endTime - startTime));
    }
    /**
     * 使用传统IO的流读写方式实现
     * @throws IOException
     */
    private static void coypByStream() throws IOException {
        long startTime = System.currentTimeMillis();
        FileInputStream fin = new FileInputStream(FROM_FILE);
        FileOutputStream fout = new FileOutputStream("G:/to6.rar");
        byte[] buffer = new byte[BUFFER_SIZE];
        while (true) {
            int ins = fin.read(buffer);
            if (ins == -1) {
                fin.close();
                fout.flush();
                fout.close();
                break;
            else{
                fout.write(buffer, 0, ins);
            }             
        }
        long endTime = System.currentTimeMillis();
        System.out.println("coypByStream time consumed(buffer size take effect) : " + (endTime - startTime));
    }
}

  • 测试结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    File :G:/from_42MB.rar ---- Buffer Size : 1024--------------
    coypByMbb time consumed(buffer size no effect) : 47
    copyByNioTransferFrom time consumed(buffer size no effect) : 62
    copyByNioTransferTo time consumed(buffer size no effect) : 47
    coypByBufferRead time consumed(buffer size take effect) : 249
    coypByFastBufferRead time consumed(buffer size take effect) : 188
    coypByStream time consumed(buffer size take effect) : 187
              
    File :G:/from_42MB.rar ---- Buffer Size : 4096--------------
    coypByMbb time consumed(buffer size no effect) : 15
    copyByNioTransferFrom time consumed(buffer size no effect) : 16
    copyByNioTransferTo time consumed(buffer size no effect) : 31
    coypByBufferRead time consumed(buffer size take effect) : 125
    coypByFastBufferRead time consumed(buffer size take effect) : 79
    coypByStream time consumed(buffer size take effect) : 93
              
    File :G:/from_42MB.rar ---- Buffer Size : 10240--------------
    coypByMbb time consumed(buffer size no effect) : 16
    copyByNioTransferFrom time consumed(buffer size no effect) : 32
    copyByNioTransferTo time consumed(buffer size no effect) : 31
    coypByBufferRead time consumed(buffer size take effect) : 78
    coypByFastBufferRead time consumed(buffer size take effect) : 62
    coypByStream time consumed(buffer size take effect) : 63
              
    File :G:/from_350MB.rar ---- Buffer Size : 1024--------------
    coypByMbb time consumed(buffer size no effect) : 280
    copyByNioTransferFrom time consumed(buffer size no effect) : 453
    copyByNioTransferTo time consumed(buffer size no effect) : 7785
    coypByBufferRead time consumed(buffer size take effect) : 8144
    coypByFastBufferRead time consumed(buffer size take effect) : 7068
    coypByStream time consumed(buffer size take effect) : 8503
              
    File :G:/from_350MB.rar ---- Buffer Size : 4096--------------
    coypByMbb time consumed(buffer size no effect) : 1904
    copyByNioTransferFrom time consumed(buffer size no effect) : 5978
    copyByNioTransferTo time consumed(buffer size no effect) : 7379
    coypByBufferRead time consumed(buffer size take effect) : 7621
    coypByFastBufferRead time consumed(buffer size take effect) : 7474
    coypByStream time consumed(buffer size take effect) : 8200
              
    File :G:/from_350MB.rar ---- Buffer Size : 10240--------------
    coypByMbb time consumed(buffer size no effect) : 328
    copyByNioTransferFrom time consumed(buffer size no effect) : 6864
    copyByNioTransferTo time consumed(buffer size no effect) : 7021
    coypByBufferRead time consumed(buffer size take effect) : 7199
    coypByFastBufferRead time consumed(buffer size take effect) : 7941
    coypByStream time consumed(buffer size take effect) : 7801

本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1272956,如需转载请自行联系原作者

Java实现文件拷贝相关推荐

  1. Java实现文件拷贝,以及修改文件扩展名

    Java实现文件拷贝,以及修改文件扩展名 方法一:单纯实现文件拷贝 public File createNewFile(String path, String realPath, String new ...

  2. cmd 将文件夹下文件剪切到另外一个文件_总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇...

    本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...

  3. java 文件 剪切_总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇

    本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 很多朋友在看我的<java IO总结系列>之前觉得创建文件.文件夹删除文件这些基础操作真的是太简单了.但看了我的文章之后,有小 ...

  4. Java实现剪切MP3格式的文件_总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇...

    本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 很多朋友在看我的<java IO总结系列>之前觉得创建文件.文件夹删除文件这些基础操作真的是太简单了.但看了我的文章之后,有小 ...

  5. java中怎么剪切文件_总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇

    本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 很多朋友在看我的<java IO总结系列>之前觉得创建文件.文件夹删除文件这些基础操作真的是太简单了.但看了我的文章之后,有小 ...

  6. java拷贝压缩文件_Android java, 快速文件拷贝,文件压缩,获得系统时间 | 学步园...

    1. 最快速度的文件拷贝,管道对管道. /** * Create report file. * @param srcFile * @param dstFile */ private void Crea ...

  7. java中文件拷贝的几种方式

    1.使用文件工具类静态方法直接拷贝 public static void copyFileByStream(File file, File fileTo) throws IOException {Fi ...

  8. java 局域网文件拷贝文件_局域网使用Java进行文件传输

    package com.herley; /** * * 客户端 */ import java.io.File; import java.io.FileInputStream; import java. ...

  9. Java 实现文件拷贝粘贴

    思路 创建输入流对象 创建输出流对象 读写字节流,复制文件 此方法适合一切文件的复制粘贴,因为所有文件底层都是字节 代码 public class CopyDemo {public static vo ...

最新文章

  1. java webservice 依赖_java开发webservice的几种方式
  2. 一份传世典文:十年编程(Teach Yourself Programming in Ten Years)
  3. sublime_text3代码自动提示补全
  4. 新型RNN:将层内神经元相互独立以提高长程记忆 | CVPR 2018论文解读
  5. c++类对象 指针区别
  6. 12月23号 Foundation库NSString操作
  7. Angular jasmine spied Method toHaveBeenCalled的执行原理
  8. 日志钩子(JournalRecord Hook)的使用
  9. 微型计算机中的80586指,一级B考试模拟试题-套,DOS版本:6.0
  10. 微软推出免费虚拟太空望远镜软件WWT
  11. 日历的java包_java11教程--包java.time.chrono介绍
  12. php-fpm性能优化
  13. python 老师和父亲_父亲节丨有个当老师的爸爸是怎样的体验
  14. po 价格条件表_SAP 定价
  15. linux怎么用jconsole_linux中jconsole
  16. 如何清空matlab命令窗口,matlab如何清空命令窗口中的内容
  17. 淘宝 喵铺脚本自动签到脚本
  18. 网站漏洞修复之最新版本UEditor漏洞
  19. luat string常用函数详解
  20. oracle里有没有stuff,STUFF函數在SQL Server和ORACLE中

热门文章

  1. [C#]从URL中获取路径的最简单方法-new Uri(url).AbsolutePath
  2. IE相关的一些BUG汇总
  3. apache 模块编译选项
  4. 推荐一篇文章,感觉学完Iterator模式后应当读一读
  5. Winform开发框架中工作流模块之审批会签操作
  6. FreeRTOS 临界段和开关中断
  7. C++通过GSoap访问webService
  8. Python中读取、显示和保存图片的方法
  9. SpringCloud微服务注册中心如何承载大型系统的千万级访问?源码及原理分析
  10. Android Studio 填坑指南