java实现文件夹对比,文件复制的 4 种实现方式及性能对比

尽管Java提供了java.io.File这样一个操作文件的类,但并没有提供一个复制文件的方法。

然而,当我们需要对磁盘上的文件进行处理的时候,这是一个很重要的方法。在这个时候我们往往不得不自己实现这样一个完成文件复制操作的方法。下面将会介绍4种常见的文件复制的实现,并比较下它们的性能。

使用FileStream

能找到的最常见经典例子。从文件A的输入流读取一批字节,写到文件B的输出流。

public static void copy(String from, String to, int bufferSize) {

InputStream in = null;

OutputStream out = null;

try {

in = new FileInputStream(new File(from));

out = new FileOutputStream(new File(to));

byte[] buffer = new byte[bufferSize];

int len;

while ((len = in.read(buffer)) > 0) {

out.write(buffer, 0, len);

}

} catch (Exception e) {

Log.w(TAG + ":copy", "error occur while copy", e);

} finally {

safelyClose(TAG + ":copy", in);

safelyClose(TAG + ":copy", out);

}

}

复制代码

如你所见,这种实现方式需要多次读取数据,再写入将数据写入,因此受限于我们提供的buffer的大小,他的效率有点一般。

使用FileChannel

Java NIO类库里引入了一个叫transferFrom的方法,文档里说这是一个会比FileStream方式更快的复制操作。

public static void copyNio(String from, String to) {

FileChannel input = null;

FileChannel output = null;

try {

input = new FileInputStream(new File(from)).getChannel();

output = new FileOutputStream(new File(to)).getChannel();

output.transferFrom(input, 0, input.size());

} catch (Exception e) {

Log.w(TAG + "copyNio", "error occur while copy", e);

} finally {

safelyClose(TAG + "copyNio", input);

safelyClose(TAG + "copyNio", output);

}

}

复制代码

使用Apache Commons IO

Appache Commons IO 提供了一个FileUtils.copyFile(File from, File to)方法用于文件复制,如果项目里使用到了这个类库,使用这个方法是个不错的选择。它的内部也是使用Java NIO的FileChannel实现的。

private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {

FileUtils.copyFile(source, dest);

}

复制代码

使用Java 7 的Files类

如果对Java 7 的使用有经验的话,那应该接触过Files这个工具类。

private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {

FileUtils.copyFile(source, dest);

}

复制代码

性能

由于项目里没用到Apache Common IO,Android也不支持Java 7,因此我只测试了前两种,数据如下:

复制文件,大小2M

buffer大小

耗时

512

455

1024

238

2048

131

4096

82

8192

46

16384

36

32768

30

65536

29

131072

26

NIO方式

31

复制文件,大小4.5M

buffer大小

耗时

512

937

1024

523

2048

315

4096

155

8192

104

16384

108

32768

83

65536

74

131072

79

NIO方式

75

复制文件,大小8M

buffer大小

耗时

512

1774

1024

942

2048

488

4096

311

8192

225

16384

169

32768

154

65536

129

131072

121

NIO方式

108

复制文件,大小161M

buffer大小

耗时

512

38561

1024

19994

2048

10747

4096

5500

8192

3857

16384

3327

32768

3201

65536

3288

131072

3281

NIO方式

3266

结论

从数据上可以看出,使用FileStream的方式,复制的效率跟我们的buffer大小取值关系很大,这无疑加大了我们使用它进行文件复制的负担。

而NIO的方式则不然,无论是小文件、还是大文件,它的效率都跟我们测试FileStream的最好水平相当!

因此,把FileStream这种老旧的实现方式从项目里挪走吧,是时候用上FileChannel了。

Written with StackEdit.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Fastcopy功能特点 1.完全支持拖曳操作,支持拖曳多个文件到来源中; 2.支持外壳整合,方便利用右键菜单直接复制文件; 3.支持三不同的HDD模式; 4.内建多人性化的操作模式; 5.支持过滤,可以使用通配符; 6.支持任务管理; 7.支持命令行操作; 8.软件十分小巧,甚至可以在安装后,直接将安装目录中的文件复制到任何可移动存储设备中,方便携带,随取随用; 9.所有的复制操作都是通过“从介质(硬盘)读数→写入数→从缓存中读出→向介质(硬盘)写入数”这几项步骤来完成的,并且这些步骤都是多个线程同时进行的,如果线程之间的协同运作不够完美,那速度就会大打折扣,有些线程忙得要命,而有些却必须等待,FASTCOPY就是优化了它们之间的工作顺序,大大提高了速度。 10.易于使用,能够充分挖掘文件系统和硬盘的传输能力。 11.支持计数和计时,在很多专业的硬盘传输速度的评测中,FastCopy 成了不二之选! Fastcopy使用 1、指定源目录、目标目录 点击“源目录”、“目标目录”可以分别为其指定要复制的内容及目标文件夹复制的内容可以是文件夹文件。目标目录结尾键入“\”表示拷贝时要包括源目录本身及其内容;结尾不键入“\”表示只拷贝源目录下的内容。 用拖拽的方式同样可以指定源目录、目标目录。这样很方便,随着在资源管理器中浏览就可以将复制对象确定下来。另外,可以通过“设置”菜单中的“外壳扩展”为右键菜单建立“复制”与“删除”命令。 2、选择不同的操作方式 通过“目标目录”文本框下的下拉菜单按钮就可以挑选七不同的操作方式。这里,复制项相对多些,都是在复制时经常会遇到的处理办法。 “移动”项是将“源目录”内容移动到“目标目录”中去,源目录内容消失;“全部删除”项是关闭“目标目录”,只对源目录内容进行处理。对于固定拷贝的操作可以建立一个任务,通过“任务菜单”菜单中的“添加/更新/删除”命令创建,方便一键就可复制或删除。 3、常规设置、硬盘模式定义 在“设置→常规设置”菜单中可以定义缓存的空间大小,它直接关系到复制时的速度快慢,现在机器配置都很强悍,这里设定值高些不成问题。相关的定义有I/O缓存设置、I/O设置、复制和删除、日志写入等项目。 硬盘模式的设置是为了在读写时对缓存的操作方式,默认下为自动硬盘模式,另外两分别是相同硬盘模式、不同硬盘模式,可以根自己机器的配置来选择。相同硬盘模式是指用大的缓存进行读入,直到缓存满额,再转入大缓存写入;不同硬盘模式则是读写缓存多线程并行进行。 4、执行后的结果查询 在执行过程中会显示读取、写入、时间、传输效率文件速率等信息,在下方的文本框中会显示当前拷贝的内容。拷贝完成后点击“显示列表”按钮可以查看拷贝内容及错误文件、目录信息。 软件对于拷贝和删除小文件文件夹来讲,可能就有点大材小用了。对于大型的文件文件夹就不同了,它能非常迅速的完成要拷贝的内容,通过简单的设置还能过滤不要的内容。体积小、方便携带、操作迅速。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值