要说到文件拷贝,我们最先想到的估计就是,使用Java原生的InputStream和OutputStream了,实现一边读取一边拷贝。下面就来实现以下。流操作均使用try-with-resource,让Java自己去关闭流的连接。

1、Java原生实现

声明一点:什么叫做追加,下面是我个人通过试验,得出的自我理解:追加是指io流关闭之后再启动一个io往里写才算追加。可以使用小的缓冲字节数组进行验证。

@Test
public void fileCopy(){
    try(InputStream is = new FileInputStream("src.txt");
        OutputStream os = new FileOutputStream("dest.txt", true)){  //注意OS的第二参数,是否追加。
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len=is.read(buffer)) != -1){
            os.write(buffer, 0, len);
        }
        System.out.println("拷贝完成");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2、使用apache的commons-io工具类

这个工具类跟我一开始的想法很吻合,就应该是直接用输入流输出流上这样多符合我们生活中常识啊。我一开始想着Java自己应该实现这个功能了吧,找了一圈发现自己天真了。不过还好别人帮我们实现了,也一样。

下面这个方法只能拷贝2G以内的文件。它会首先判断你这个文件是否大于2G,如果大于就不进行后续的拷贝了,直接返回-1。小于2G就去拷贝,并返回我们这个文件的大小。

@Test
public void fileCopy(){
    try(InputStream in = new FileInputStream("src.txt");
        OutputStream out = new FileOutputStream("dest.txt", true)){
        int count = IOUtils.copy(in, out);  //啧啧,这多和谐啊。
        System.out.println(count);
        System.out.println("拷贝完成");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

只能拷贝2G太不爽了,我一个小电影就3G多,你这个方法有点逊啊。

2.1 大文件的拷贝

能拷贝大文件首先你名字就要有大的样子,确实copy大文件的名字就比copy多了一个large,把名字换成copyLarge就可以了,什么都不用动。返回值也是文件的大小。

copycopyLarge有很多重载的方法,不过就这两个就够用了。

3、使用Java的java.nio

原来Java还真实现了,看来我只真的天真了。

@Test
public void fileCopy(){
    try(FileChannel in = new FileInputStream("src.txt").getChannel();
        FileChannel out = new FileOutputStream("dest.txt", true).getChannel()){
        out.transferFrom(in, 0, in.size());
        System.out.println("拷贝完成");
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Java的FIles类实现

@Test
public void fileCopy(){
    try {
        Files.copy(Paths.get("src.txt"), Paths.get("dest.txt"));  //如果dest文件存在就会报错
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("拷贝完成");
}

4、怎么能少了我们的Guava呢

4.1 文件对文件,不支持追加

我们不用担心文件存不存在,如果文件不存在的话,他会帮我们创建

@Test
public void fileCopy(){
    File src = new File("src.txt");
    File dest = new File("dest.txt");
    try {
        Files.copy(src, dest);
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("拷贝完成");
}
4.2支持追加,文件对字节输出流OutputStream
@Test
public void fileCopy(){
    File src = new File("src.txt");
    try (OutputStream out = new FileOutputStream("dest.txt", true)){
        Files.copy(src, out);
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("拷贝完成");
}