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 = 127572360


Time taken by FileChannels Copy = 10449963


Time taken by Java7 Files Copy = 10808333


Time taken by Apache Commons IO Copy = 17971677

 

原文地址:https://www.cnblogs.com/xxjcai/p/11581987.html

时间: 2024-08-28 12:16:29

java中文件复制的4种方式的相关文章

Java实现文件复制的四种方式

背景:有很多的Java初学者对于文件复制的操作总是搞不懂,下面我将用4中方式实现指定文件的复制. 实现方式一:使用FileInputStream/FileOutputStream字节流进行文件的复制操作 1 private static void streamCopyFile(File srcFile, File desFile) throws IOException { 2 // 使用字节流进行文件复制 3 FileInputStream fi = new FileInputStream(sr

java中获取路径的几种方式

总是忘记, 备份一下,方便下次用. 第一种: File directory = new File("");//参数为空 String courseFile = directory.getCanonicalPath() ;System.out.println(courseFile); 结果:C:\Documents and Settings\Administrator\workspace\projectName获取当前类的所在工程路径; 第二种: File f = new File(th

JAVA中集合输出的四种方式

在JAVA中Collection输出有四种方式,分别如下: 一) Iterator输出. 该方式适用于Collection的所有子类. public class Hello { public static void main(String[] args) throws Exception { Set<Person> javaProgramers = new HashSet<Person>(); javaProgramers.add(new Person("aaron&qu

java中设置代理的两种方式

1 前言 有时候我们的程序中要提供可以使用代理访问网络,代理的方式包括http.https.ftp.socks代理.比如在IE浏览器设置代理. 那我们在我们的java程序中使用代理呢,有如下两种方式.直接上代码. 2 采用设置系统属性 ? 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 import jav

JAVA中Arrays.sort()使用两种方式(Comparable和Comparator接口)对对象或者引用进行排序

一.描述 自定义的类要按照一定的方式进行排序,比如一个Person类要按照年龄进行从小到大排序,比如一个Student类要按照成绩进行由高到低排序. 这里我们采用两种方式,一种是使用Comparable接口:让待排序对象所在的类实现Comparable接口,并重写Comparable接口中的compareTo()方法,缺点是只能按照一种规则排序. 另一种方式是使用Comparator接口:编写多个排序方式类实现Comparator接口,并重写新Comparator接口中的compare()方法,

JAVA中创建字符串的两种方式的区别

我们知道,通常在Java中创建一个字符串会有两种方式,通过双引号直接赋值和通过构造器来创建. String x = "abcd"; String y = new String("abcd"); 然而,这两种方式之间的区别是什么?分别应用于哪些情况,之前还不是很懂. 1.双引号的方式 String x = "abcd"; String y = "abcd"; System.out.println(x==y);//true Sys

Java中实现多线程的两种方式之间的区别

Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线程,有两种方法: ◆需要从Java.lang.Thread类派生一个新的线程类,重载它的run()方法:  ◆实现Runnalbe接口,重载Runnalbe接口中的run()方法. 为什么Java要提供两种方法来创建线程呢?它们都有哪些区别?相比而言,哪一种方法更好呢? 在Java中,类仅支持单继承

java中终止线程的三种方式

在java中有三种方式可以终止线程.分别为: 1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止.  2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend.resume一样,也可能发生不可预料的结果). 3.  使用interrupt方法中断线程. 下面我们来详细的介绍这三种方法. 1. 使用退出标志终止线程 当run方法执行完后,线程就会退出.但有时run方法是永远不会结束的.如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处

java中String初始化的两种方式

转自:http://www.diybl.com/course/3_program/java/javajs/2007104/75886.html       字符串可能是任何程序语言中都会出现的对象,java中创建并初始化一个String对象,最常见的方式有两种: String str=new String("XXX"); String str="XXX"; 二者看似相同,其实有很大的差别.       前者是java中标准的对象创建方式,其创建的对象将直接放置到堆中