测试环境: jdk 1.7 +  2G内存

测试代码基本上复制了: http://blog.csdn.net/tabactivity/article/details/9317143

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
package test;
 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
 
import java.io.FileInputStream;
 
import java.io.FileOutputStream;
 
import java.nio.MappedByteBuffer;
 
import java.nio.channels.FileChannel;
 
public class FileCopyTest
{
 
    public FileCopyTest()
    {
        File[] files = new File("c:/images").listFiles();
        String destFolderPath = "g:/images";
 
        long t = System.currentTimeMillis();
 
        try
        {
            for (File sourceFile : files)
            {
                traditionalCopy(sourceFile.getPath(), destFolderPath + "/" + sourceFile.getName());
            }
 
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        System.out.println("传统IO方法实现文件拷贝耗时:" + (System.currentTimeMillis() - t) + "ms");
 
        //删除刚刚创建的
        for (File file : new File(destFolderPath).listFiles())
        {
            file.delete();
        }
 
        t = System.currentTimeMillis();
        try
        {
            for (File sourceFile : files)
            {
                copyBIO(sourceFile.getPath(), destFolderPath + "/" + sourceFile.getName());
            }
 
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        System.out.println("传统IO + 缓存 方法实现文件拷贝耗时:" + (System.currentTimeMillis() - t) + "ms");
 
        //删除刚刚创建的
        for (File file : new File(destFolderPath).listFiles())
        {
            file.delete();
        }
 
        t = System.currentTimeMillis();
        try
        {
            for (File sourceFile : files)
            {
                nioCopy(sourceFile.getPath(), destFolderPath + "/" + sourceFile.getName());
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        System.out.println("利用NIO文件通道方法实现文件拷贝耗时:" + (System.currentTimeMillis() - t) + "ms");
 
        //删除刚刚创建的
        for (File file : new File(destFolderPath).listFiles())
        {
            file.delete();
        }
 
        t = System.currentTimeMillis();
        try
        {
            for (File sourceFile : files)
            {
                nioCopy2(sourceFile.getPath(), destFolderPath + "/" + sourceFile.getName());
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        System.out.println("利用NIO文件内存映射及文件通道实现文件拷贝耗时:" + (System.currentTimeMillis() - t) + "ms");
 
        //删除刚刚创建的
        for (File file : new File(destFolderPath).listFiles())
        {
            file.delete();
        }
 
    }
 
    private static void traditionalCopy(String sourcePath, String destPath) throws Exception
    {
        File source = new File(sourcePath);
        File dest = new File(destPath);
 
        FileInputStream fis = new FileInputStream(source);
        FileOutputStream fos = new FileOutputStream(dest);
         
        byte[] buf = new byte[8192];
        int len = 0;
 
        while ((len = fis.read(buf)) != -1)
        {
            fos.write(buf, 0, len);
        }
 
        fis.close();
        fos.close();
    }
 
    private static void copyBIO(String sourcePath, String destPath) throws Exception
    {
        File source = new File(sourcePath);
        File dest = new File(destPath);
 
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(source));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest));
 
        byte[] buf = new byte[8192];
        int len = 0;
        while ((len = bis.read(buf)) != -1)
        {
            bos.write(buf, 0, len);
        }
 
        bis.close();
        bos.close();
    }
 
    private static void nioCopy(String sourcePath, String destPath) throws Exception
    {
        File source = new File(sourcePath);
        File dest = new File(destPath);
 
        FileInputStream fis = new FileInputStream(source);
        FileOutputStream fos = new FileOutputStream(dest);
 
        FileChannel sourceCh = fis.getChannel();
        FileChannel destCh = fos.getChannel();
 
        destCh.transferFrom(sourceCh, 0, sourceCh.size());
 
        sourceCh.close();
        destCh.close();
 
    }
 
    private static void nioCopy2(String sourcePath, String destPath) throws Exception
    {
        File source = new File(sourcePath);
        File dest = new File(destPath);
 
        FileInputStream fis = new FileInputStream(source);
        FileOutputStream fos = new FileOutputStream(dest);
 
        FileChannel sourceCh = fis.getChannel();
        FileChannel destCh = fos.getChannel();
 
        MappedByteBuffer mbb = sourceCh.map(FileChannel.MapMode.READ_ONLY, 0, sourceCh.size());
 
        destCh.write(mbb);
 
        sourceCh.close();
        destCh.close();
    }
 
}

测试结果有些地方还是感到意外:

复制到同一块硬盘的其他分区, 总文件大小: 33M,其中一个文件:16M

-----------------------------------------------------------------------------

传统IO方法实现文件拷贝耗时:1156ms

传统IO + 缓存 方法实现文件拷贝耗时:1312ms

利用NIO文件通道方法实现文件拷贝耗时:1109ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:891ms

传统IO方法实现文件拷贝耗时:1157ms

传统IO + 缓存 方法实现文件拷贝耗时:1312ms

利用NIO文件通道方法实现文件拷贝耗时:1078ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:891ms

传统IO方法实现文件拷贝耗时:1203ms

传统IO + 缓存 方法实现文件拷贝耗时:1172ms

利用NIO文件通道方法实现文件拷贝耗时:1157ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:891ms

传统IO方法实现文件拷贝耗时:984ms

传统IO + 缓存 方法实现文件拷贝耗时:984ms

利用NIO文件通道方法实现文件拷贝耗时:1172ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:938ms

复制到另一个硬盘, 总文件大小: 33M,其中一个文件:16M

-----------------------------------------------------------------------------

传统IO方法实现文件拷贝耗时:1110ms

传统IO + 缓存 方法实现文件拷贝耗时:1343ms

利用NIO文件通道方法实现文件拷贝耗时:984ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:937ms

传统IO方法实现文件拷贝耗时:985ms

传统IO + 缓存 方法实现文件拷贝耗时:1516ms

利用NIO文件通道方法实现文件拷贝耗时:1203ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:890ms

传统IO方法实现文件拷贝耗时:875ms

传统IO + 缓存 方法实现文件拷贝耗时:1203ms

利用NIO文件通道方法实现文件拷贝耗时:1391ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:1031ms

传统IO方法实现文件拷贝耗时:938ms

传统IO + 缓存 方法实现文件拷贝耗时:1266ms

利用NIO文件通道方法实现文件拷贝耗时:1453ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:968ms

复制到另一个硬盘, 总文件大小: 81M,其中一个文件:66M

-----------------------------------------------------------------------------

传统IO方法实现文件拷贝耗时:4812ms

传统IO + 缓存 方法实现文件拷贝耗时:6250ms

利用NIO文件通道方法实现文件拷贝耗时:3375ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:3453ms

传统IO方法实现文件拷贝耗时:5328ms

传统IO + 缓存 方法实现文件拷贝耗时:6110ms

利用NIO文件通道方法实现文件拷贝耗时:3766ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:3641ms

复制到移动硬盘(用了3年), 总文件大小: 33M,其中一个文件:16M

-----------------------------------------------------------------------------

传统IO方法实现文件拷贝耗时:16532ms

传统IO + 缓存 方法实现文件拷贝耗时:15828ms

利用NIO文件通道方法实现文件拷贝耗时:34437ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:34797ms

传统IO方法实现文件拷贝耗时:20672ms

传统IO + 缓存 方法实现文件拷贝耗时:19547ms

利用NIO文件通道方法实现文件拷贝耗时:33844ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:33375ms

复制到移动硬盘(用了3年), 总文件大小: 15M,单个文件:150KB左右。

-----------------------------------------------------------------------------

传统IO方法实现文件拷贝耗时:172ms

传统IO + 缓存 方法实现文件拷贝耗时:157ms

利用NIO文件通道方法实现文件拷贝耗时:188ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:313ms

传统IO方法实现文件拷贝耗时:156ms

传统IO + 缓存 方法实现文件拷贝耗时:156ms

利用NIO文件通道方法实现文件拷贝耗时:188ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:344ms

传统IO方法实现文件拷贝耗时:203ms

传统IO + 缓存 方法实现文件拷贝耗时:218ms

利用NIO文件通道方法实现文件拷贝耗时:187ms

利用NIO文件内存映射及文件通道实现文件拷贝耗时:282ms

总结:

1. 根据上面的测试结果表明,如果拷贝的是小文件(单个文件几百KB),使用NIO并不会比IO快.

如果拷贝的单个文件达到几十M+,使用NIO速度会快的比较明显。

2. 测试时还发现 traditionalCopy()无论处理小文件还是大文件都不比copyBIO()慢。

traditionalCopy()就是使用最基本的 FileInputStream 和 FileOutStream。

copyBIO()使用的是BufferedInputStream 和 BufferedOutputStream。

关于这一点,可能是因为 “从1.5开始,Java对InputStream/OutputStream 进行了重新改写,用的就是NIO,因此,就算你不显示声明要用NIO,只要你的类继承了InputStream/OutputStream就已经在用NIO了”

参考资料: http://zhidao.baidu.com/question/109313742.html

3. 测试拷贝到移动硬盘上时,使用传统的IO比NIO速度还快,并且快很多。(这块移动硬盘用了3年,写入速度不怎么样)

这个原因我无法解释,有谁能告诉我?

2014-03-02

文件拷贝, 使用 BIO,NIO的对比,四种写法性能分析。的更多相关文章

  1. 17_点击事件第四种写法_布局文件添加onclick属性

    尽量不要用第四种点击事件的写法.在一万多行代码中发现了一个没被调用的代码 public void call(View v){//第四种写法参数一定是View v //public void call( ...

  2. Android代码规范----按钮单击事件的四种写法

    [前言] 按钮少的时候用第三种的匿名内部类会比较快,比如写demo测试的时候或者登陆界面之类. 按钮多的时候一般选择第四种写法. 一.第一种写法:在XML文件中声明onClick属性(很少用) 在XM ...

  3. [0413] FFTSHIFT的四种写法

    FFTSHIFT的四种写法 前言 matlab说,"你读过书,--我便考你一考.fftshift的函数,怎样写的?"我想,讨饭一样的人,也配考我么?便回过脸去,不再理会.matla ...

  4. Android中点击事件的四种写法详解

    Android中点击事件的四种写法 使用内部类实现点击事件 使用匿名内部类实现点击事件 让MainActivity实现View.OnClickListener接口 通过布局文件中控件的属性 第一种方法 ...

  5. 茴香豆的“茴”有四种写法,Python的格式化字符串也有

    茴香豆的"茴"有四种写法,Python的格式化字符串也有 茴香豆的"茴"有四种写法,Python的格式化字符串也有 被低估的断言 多一个逗号,少一点糟心事 上下 ...

  6. swap函数的四种写法

    swap 函数的四种写法 (1)经典型 --- 嫁衣法 void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } ( ...

  7. AX中四种库存ABC分析法原理研究

    库存ABC分类,简单的说就是抓大放小,是为了让我们抓住重点,用最大精力来管理最重要的物料,而对于不太重要的物料则可以用较少的精力进行管理.它和我们平常说的八二法则有异曲同工之妙. 既然要应用库存ABC ...

  8. JS 获取星期几的四种写法

    今天是星期几的4种JS代码写法,有需要的朋友可以参考一下 第一种写法 复制代码代码如下: var str = "";  var week = new Date().getDay() ...

  9. Python中斐波那契数列的四种写法

    在这些时候,我可以附和着笑,项目经理是决不责备的.而且项目经理见了孔乙己,也每每这样问他,引人发笑.孔乙己自己知道不能和他们谈天,便只好向新人说话.有一回对我说道,“你学过数据结构吗?”我略略点一点头 ...

随机推荐

  1. BugkuCTF sql注入

    前言 写了这么久的web题,算是把它基础部分都刷完了一遍,以下的几天将持续更新BugkuCTF WEB部分的题解,为了不影响阅读,所以每道题的题解都以单独一篇文章的形式发表,感谢大家一直以来的支持和理 ...

  2. python2.6升级到3.3.0 以及依赖库在迁移时的处理

    线上服务器python版本默认是2.6,由于业务程序要求,需要将python升级到3.3.0, 操作记录如下: Cenots6.8默认安装的是2.6版本,要更新升级需安装下gcc: [root@ope ...

  3. JS中的跨域问题

    一.什么是跨域? 1.定义:跨域是指从一个域名的网页去请求另一个域名的资源.比如从www.baidu.com 页面去请求 www.google.com 的资源.但是一般情况下不能这么做,它是由浏览器的 ...

  4. 个人博客作业Week2 是否需要有代码规范

    问题:是否需要有代码规范 对于是否需要有代码规范,请考虑下列论点并反驳/支持: 1.这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 2.我是个艺术家,手艺人,我有 ...

  5. Scrum Meeting NO.7

    Scrum Meeting No.7 1.会议内容 经过老师提醒,我们认识到,应尽快把主要功能实现,其他的细枝末节应在这之后慢慢添加.当今最重要的任务是和online组和数据处理组实现数据共享. 此外 ...

  6. 【MOOC EXP】Linux内核分析实验六报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 进程的描述和进程的创建 知识点梳理: ...

  7. 小学生四则运算APP核心代码公布

    Mainactivity类: package com.example.XXSCYS; import java.io.ByteArrayOutputStream; import java.io.File ...

  8. Distances to Zero CodeForces - 803B (二分)

    题目链接:https://vjudge.net/problem/CodeForces-803B#author=0 题意: 给你一个数组,其中至少包括一个0,求每一个元素距离最近一个0的距离是多少. 样 ...

  9. 快速简化Android截屏工作

    1.安装Notepad++v6.9 2.插件管理器里Plugin Manager安装AndroidLogger 3.AndroidLogger里的capture功能抓取Android的当前屏幕截图到w ...

  10. PSP(5.4——5.10)以及周记录

    1.PSP 5.4 14:00 17:00 70 110 讨论班 A Y min 5.5 10:00 16:50 125 285 Cordova A Y min 5.6 13:30 15:00 35 ...