java中文件复制的4种方式
今天一个同事问我文件复制的问题,他一个100M的文件复制的指定目录下竟然成了1G多,吓我一跳,后来看了他的代码发现是自己通过字节流复制的,定义的字节数组很大,导致复制后目标文件非常大,其实就是空行等一些无效空间。我也是很少用这种方式拷贝问价,大多数用Apache提供的commons-io中的FileUtils,后来在网上查了下,发现还有其他的方式,效率更高,所以在此整理一下,也是自己的一个学习。
1. 使用FileStreams复制
比较经典的一个代码,使用FileInputStream读取文件A的字节,使用FileOutputStream写入到文件B。
public static void copy(String source, String dest, int bufferSize) {
    InputStream in = null;
    OutputStream out = null;
    try {
        in = new FileInputStream(new File(source));
        out = new FileOutputStream(new File(dest));
        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);
    }
}   
2.2、使用FileChannel
Java NIO包括transferFrom方法,根据文档应该比文件流复制的速度更快。
public static void copyNio(String source, String dest) {
    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);
    }
}
3、 使用Apache Commons IO复制
Appache Commons IO 提供了一个FileUtils.copyFile(File from, File to)方法用于文件复制,如果项目里使用到了这个类库,使用这个方法是个不错的选择。
它的内部也是使用Java NIO的FileChannel实现的。
commons-io的路径:http://commons.apache.org/proper/commons-io/javadocs/api-release/index.html。里面还有很多实用的方法,如拷贝目录、拷贝指定格式文件等。
private static void  copyFileByApacheCommonsIO(File source, File dest) throws IOException {
    FileUtils.copyFile(source, dest);
}4、使用Java7的Files类复制
private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
    Files.copy(source.toPath(), dest.toPath());
}我没有亲测,找了下网友的测试程序和输出,性能数据供大家参考(来源:https://www.jb51.net/article/70412.htm)
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.nio.channels.FileChannel;import java.nio.file.Files;import org.apache.commons.io.FileUtils;public class CopyFilesExample {  public static void main(String[] args) throws InterruptedException,      IOException {    File source = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile1.txt");    File dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile1.txt");      // copy file using FileStreams    long start = System.nanoTime();    long end;    copyFileUsingFileStreams(source, dest);    System.out.println("Time taken by FileStreams Copy = "        + (System.nanoTime() - start));    // copy files using java.nio.FileChannel    source = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile2.txt");    dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile2.txt");    start = System.nanoTime();    copyFileUsingFileChannels(source, dest);    end = System.nanoTime();    System.out.println("Time taken by FileChannels Copy = " + (end - start));    // copy file using Java 7 Files class    source = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile3.txt");    dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile3.txt");    start = System.nanoTime();    copyFileUsingJava7Files(source, dest);    end = System.nanoTime();    System.out.println("Time taken by Java7 Files Copy = " + (end - start));    // copy files using apache commons io    source = new File("C:\\Users\\nikos7\\Desktop\\files\\sourcefile4.txt");    dest = new File("C:\\Users\\nikos7\\Desktop\\files\\destfile4.txt");    start = System.nanoTime();    copyFileUsingApacheCommonsIO(source, dest);    end = System.nanoTime();    System.out.println("Time taken by Apache Commons IO Copy = "        + (end - start));  }  private static void copyFileUsingFileStreams(File source, File dest)      throws IOException {    InputStream input = null;    OutputStream output = null;    try {      input = new FileInputStream(source);      output = new FileOutputStream(dest);      byte[] buf = new byte[1024];      int bytesRead;      while ((bytesRead = input.read(buf)) > 0) {        output.write(buf, 0, bytesRead);      }    } finally {      input.close();      output.close();    }  }  private static void copyFileUsingFileChannels(File source, File dest)      throws IOException {    FileChannel inputChannel = null;    FileChannel outputChannel = null;    try {      inputChannel = new FileInputStream(source).getChannel();      outputChannel = new FileOutputStream(dest).getChannel();      outputChannel.transferFrom(inputChannel, 0, inputChannel.size());    } finally {      inputChannel.close();      outputChannel.close();    }  }  private static void copyFileUsingJava7Files(File source, File dest)      throws IOException {    Files.copy(source.toPath(), dest.toPath());  }  private static void copyFileUsingApacheCommonsIO(File source, File dest)      throws IOException {    FileUtils.copyFile(source, dest);  }}输出:
Time taken by FileStreams Copy = 127572360Time taken by FileChannels Copy = 10449963Time taken by Java7 Files Copy = 10808333Time taken by Apache Commons IO Copy = 17971677 java中文件复制的4种方式的更多相关文章
- java中数组复制的两种方式
		在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ... 
- Java实现文件复制的四种方式
		背景:有很多的Java初学者对于文件复制的操作总是搞不懂,下面我将用4中方式实现指定文件的复制. 实现方式一:使用FileInputStream/FileOutputStream字节流进行文件的复制操 ... 
- Java中数组复制的几种方式以及数组合并
		1.Object.clone() 简单直接,只能对源数组完整地复制 2.Arrays.copyOf(T[] original, int newLength) 可以只复制源数组中部分元素,但复制的起始位 ... 
- Java中HashMap遍历的两种方式
		Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ... 
- JAVA中集合输出的四种方式
		在JAVA中Collection输出有四种方式,分别如下: 一) Iterator输出. 该方式适用于Collection的所有子类. public class Hello { public stat ... 
- java中使用mongodb的几种方式
		最近有时间看了一下mongodb,因为mongodb更容易扩展所以考虑使用mongodb来保存数据. 首先下载安装mongodb,这是很简单的,装好后使用mongod命令就可以启动数据库.正式部署的话 ... 
- java中设置代理的两种方式
		1 前言 有时候我们的程序中要提供可以使用代理访问网络,代理的方式包括http.https.ftp.socks代理.比如在IE浏览器设置代理. 那我们在我们的java程序中使用代理呢,有如下两种方式. ... 
- java中实现同步的两种方式:syschronized和lock的区别和联系
		Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我 ... 
- java中遍历集合的三种方式
		第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ... 
随机推荐
- BZOJ1014 火星人的prefix
			火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 11 字 ... 
- Python爬虫爬取异步加载的数据
			前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:努力努力再努力 爬取qq音乐歌手数据接口数据 https://y.qq ... 
- 用FPGA设计LCD 转 VGA
			这个东西其实是在上一个冬天就做完了,而且似乎已经产业化了,当时是为一位朋友做的,这个朋友再卖给产业化的人,就像流于俗套的故事一样,这个朋友拿到了钱,不过不像项目开始时说的那样与我有关.想想多年前一起吃 ... 
- dev gridcontrol绘制页脚
			gridView.OptionsView.ShowFooter = true;//启用显示页脚 //索引为1的列 gridView.Columns[1].SummaryItem.DisplayForm ... 
- 《Java基础知识》Java字符串详解
			本文内容: String类的概述 String类的使用步骤 String类的常用方法 本文目的: 能够使用String类的构造方法创建字符串对象 能够明确String类的构造方法创建对象,和直接赋值创 ... 
- 《Java基础知识》Java 泛型详解
			JDK 1.5 之后,Java 通过泛型解决了容器类型安全这一问题,而几乎所有人接触泛型也是通过Java的容器.那么泛型究竟是什么? 泛型的本质是参数化类型:也就是说,泛型就是将所操作的数据类型作为参 ... 
- 《Javascript设计模式与开发实践》--读书笔记
			第2章 this call apply bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用. bind( ... 
- IJKPlayerView设置Header播放视频的方法
			播放b站视频连接的实测图 https://github.com/Rukey7/IjkPlayerView 使用库的连接 在用这个库播放b站视频连接的时候总是播放不了 检查了一下是因为b站视频连接需要验 ... 
- Nginx代理缓存功能
			Nginx代理缓存功能 Nginx缓存主要是用于减轻后端服务器的负载,提高网站并发量,提升用户体验度. 注意:Nginx反向代理的缓存功能是由ngx_http_proxy_module提供, ... 
- Winform中实现将照片剪贴到系统剪切板中(附代码下载)
			场景 效果 点击剪切按钮 点击粘贴按钮 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免 ... 
