欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java 文件复制

程序员文章站 2022-06-10 11:10:38
...

使用FileInputStream+BufferedInputStream与FileOutputStream+BufferedOutputStream实现文件复制,是很多人普遍想到的一种方法。在这里,我将给出另外一种方法,使用FileChannel通道。其实,还有一些其他方法,想了解更多,清参见我转载的文章:JAVA NIO 简介

不多说,直接贴出源码:

srcFile和destFile:均为文件而非目录;

overlay:指示是否覆盖已存在目标文件。

 

package com.pluto.file;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class FileCopy {
	private final int BUFFER_SIZE = 4096;

	public long bufferCopyFile(File srcFile, File destFile, boolean overlay) throws FileNotFoundException {
		if (!srcFile.exists()) {
			throw new FileNotFoundException("At path " + srcFile.getAbsolutePath());
		}

		if (destFile.exists() && overlay) {
			destFile.delete();
		}

		BufferedInputStream bufin = new BufferedInputStream(new FileInputStream(srcFile));
		BufferedOutputStream bufout = new BufferedOutputStream(new FileOutputStream(destFile));
		byte[] buffer = new byte[BUFFER_SIZE];
		long totalBytesReaded = 0;
		int bytesReaded = -1;
		try {
			while ((bytesReaded = bufin.read(buffer, 0, BUFFER_SIZE)) != -1) {
				bufout.write(buffer, 0, bytesReaded);
				totalBytesReaded += bytesReaded;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				bufin.close();
				bufout.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return totalBytesReaded;
	}

	public long channelCopyFile(File srcFile, File destFile, boolean overlay) throws FileNotFoundException {
		if (!srcFile.exists()) {
			throw new FileNotFoundException("At path " + srcFile.getAbsolutePath());
		}

		if (destFile.exists() && overlay) {
			destFile.delete();
		}

		// 获取源文件和目标文件的输入输出流
		FileInputStream fin = new FileInputStream(srcFile);
		FileOutputStream fout = new FileOutputStream(destFile);
		// 获取输入输出通道
		FileChannel fcin = fin.getChannel();
		FileChannel fcout = fout.getChannel();
		long totalBytesReaded = 0;
		try{
			totalBytesReaded = fcin.transferTo(0, fcin.size(), fcout);
		}catch(IOException e){
			e.printStackTrace();
		} finally {
			try {
				fin.close();
				fout.close();
				fcin.close();
				fcout.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		return totalBytesReaded;
	}
}
 

 

在本机上面做了个简单的性能测试。在下面的测试源码中,beautiful.rmvb是一个600M左右的文件

 

 

		FileCopy fileCopy = new FileCopy();
		File srcFile = new File("/home/pluto/temporary/filecopy/beautiful.rmvb");
		File destFile1 = new File("/home/pluto/temporary/filecopy/dest/b.rmvb");
		File destFile2 = new File("/home/pluto/temporary/filecopy/dest/be.rmvb");
		long totalBytes = 0;
		long start = System.currentTimeMillis();
		try {
			totalBytes = fileCopy.bufferCopyFile(srcFile, destFile1, false);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println("bufferCopyFile: " + totalBytes + "  spend: " + (end - start));
		
		start = System.currentTimeMillis();
		try {
			totalBytes = fileCopy.channelCopyFile(srcFile, destFile2, false);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		end = System.currentTimeMillis();
		System.out.println("\nchannelCopyFile: " + totalBytes + "  spend: " + (end - start));
 

运行输出结果如下:

 

 

bufferCopyFile: 685049654  spend: 26077

channelCopyFile: 685049654  spend: 28345

 我的电脑性能一般,上面的结果只具有参考性。