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
我的电脑性能一般,上面的结果只具有参考性。