概述
对于文件的复制,平时我们都是使用输入输出流进行操作,利用源文件创建出一个输入流,然后利用目标文件创建出一个输出流,最后将输入流的数据读取写入到输出流中。这样也是可以进行操作的。但是利用fileChannel是很有用的一个方式。它能直接连接输入输出流的文件通道,将数据直接写入到目标文件中去。
优势
可防止OOM(内存溢出),高效率(后面详解)
使用
下面以复制500多M的一个本地文件主例。
方法一:使用普通方式
代码如下
/**
* 普通的文件复制方法
*
* @param fromFile 源文件
* @param toFile 目标文件
* @throws FileNotFoundException 未找到文件异常
*/
public static void fileCopyNormal(File fromFile, File toFile) throws FileNotFoundException {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = new BufferedInputStream(new FileInputStream(fromFile));
outputStream = new BufferedOutputStream(new FileOutputStream(toFile));
byte[] bytes = new byte[1024];
int i;
//读取到输入流数据,然后写入到输出流中去,实现复制
while ((i = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, i);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试方法
public static void main(String[] args) throws FileNotFoundException {
long start = System.currentTimeMillis();
File src = new File("F:\\oxygen.zip");
File dest = new File("F:\\copy_oxygen.zip");
fileCopyNormal(src,dest);
long end = System.currentTimeMillis();
System.out.println("用时:"+(end -start)+" ms");
}
运行结果
用时:659 ms
方式二:使用filechannel进行文件复制
代码如下
/**
* 用filechannel进行文件复制
*
* @param fromFile 源文件
* @param toFile 目标文件
*/
public static void fileCopyWithFileChannel(File fromFile, File toFile) {
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
FileChannel fileChannelInput = null;
FileChannel fileChannelOutput = null;
try {
fileInputStream = new FileInputStream(fromFile);
fileOutputStream = new FileOutputStream(toFile);
//得到fileInputStream的文件通道
fileChannelInput = fileInputStream.getChannel();
//得到fileOutputStream的文件通道
fileChannelOutput = fileOutputStream.getChannel();
//将fileChannelInput通道的数据,写入到fileChannelOutput通道
fileChannelInput.transferTo(0, fileChannelInput.size(), fileChannelOutput);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileInputStream != null)
fileInputStream.close();
if (fileChannelInput != null)
fileChannelInput.close();
if (fileOutputStream != null)
fileOutputStream.close();
if (fileChannelOutput != null)
fileChannelOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试方法
public static void main(String[] args) throws FileNotFoundException {
long start = System.currentTimeMillis();
File src = new File("F:\\oxygen.zip");
File dest = new File("F:\\copy_oxygen.zip");
fileCopyWithFileChannel(src,dest);
long end = System.currentTimeMillis();
System.out.println("用时:"+(end -start)+" ms");
}
运行结果
用时:340 ms
总结
使用FileChannel 效率快近一倍,并可以有效的防止OOM(内存溢出)。