几种拷贝文件的实现 package org.io;import java.io.Closeable;import java.io.DataInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;imp
package org.io;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
/***
* 拷贝文件操作类
*
* 主要涉及到一些IO操作,从传统的IO到NIO
*
* @author 陈波
*
*/
public final class CopyFileUtils {
/***
* 一次拷贝文件的大小为1MB
*/
private static final long copyOneSize = 1024L * 1024L;
/***
* 拷贝文件的方式
*
* @author
*
*/
public static enum Model {
BASIC, BYTE_BUFFER, FILE_CHANNEL, MAPPED
};
/***
* 进行文件拷贝操作
*
* @param src
* @param dest
* @param model
*/
public static final void copyFile(String src, String dest, Model model)throws IOException {
BaseCopyFile instance=CopyFileFacotry.getInstance(model);
instance.copyFile(src, dest);
}
/***
* 静态工厂方法
*
* @author 陈波
*
*/
static final class CopyFileFacotry {
public static final BaseCopyFile getInstance(Model model) {
switch (model) {
case BASIC:
return new CopyFile();
case BYTE_BUFFER:
return new CopyFileByteBuffer();
case FILE_CHANNEL:
return new CopyFileChannel();
case MAPPED:
return new CopyFileMappedByteBuffer();
default:
return new CopyFile();
}
}
}
/***
* 拷贝文件操作
*
* @author 陈波
*
*/
static abstract class BaseCopyFile {
/***
* 拷贝文件操作
*
* @param src
* @param dest
* @throws IOException
*/
protected abstract void copyFile(String src, String dest) throws IOException;
/***
* 关闭文件流操作
*
* @param closeables
* @throws IOException
*/
public void closeStream(Closeable... closeables) throws IOException {
if (null != closeables && closeables.length > 0) {
for (Closeable closeable : closeables) {
if (closeable != null) {
closeable.close();
}
}
}
}
}
/***
* 普通的拷贝操作
*
* @author 陈波
*
*/
static final class CopyFile extends BaseCopyFile {
@Override
protected void copyFile(String src, String dest) throws IOException {
DataInputStream inputStream = new DataInputStream(new FileInputStream(src));
OutputStream outputStream = new FileOutputStream(dest);
try {
int available = inputStream.available();
byte[] copyByte = null;
if (available <= copyOneSize) {
// 文件长度在1MB之内直接拷贝完毕
copyByte = new byte[available];
inputStream.readFully(copyByte);
outputStream.write(copyByte);
} else {
copyByte = new byte[(int) copyOneSize];
int len = -1;
while ((len = inputStream.read(copyByte)) > 0) {
outputStream.write(copyByte, 0, len);
}
}
} finally {
this.closeStream(inputStream, outputStream);
}
}
}
/***
* 使用ByteBuffer 拷贝数据操作
*
* @author 陈波
*
*/
static final class CopyFileByteBuffer extends BaseCopyFile {
@Override
protected void copyFile(String src, String dest) throws IOException {
FileInputStream fileInputStream = new FileInputStream(src);
FileOutputStream fileOutputStream = new FileOutputStream(dest);
try {
FileChannel inChannel = fileInputStream.getChannel();
FileChannel outChannel = fileOutputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate((int) copyOneSize);
int size = -1;
while ((size = inChannel.read(byteBuffer)) > 0) {
byteBuffer.flip();
outChannel.write(byteBuffer);
byteBuffer.clear();
}
byteBuffer.clear();
} finally {
closeStream(fileInputStream, fileOutputStream);
}
}
}
/***
* 拷贝文件使用FileChannel
*
* @author 陈波
*
*/
static final class CopyFileChannel extends BaseCopyFile {
@Override
protected void copyFile(String src, String dest) throws IOException {
File srcFile = new File(src);
File destFile = new File(dest);
FileInputStream fileInputStream = new FileInputStream(srcFile);
FileOutputStream fileOutputStream = new FileOutputStream(destFile);
try {
FileChannel inChannel = fileInputStream.getChannel();
FileChannel outChannel = fileOutputStream.getChannel();
long postion = 0;
while (postion < inChannel.size()) {
long realCopySize = outChannel.transferFrom(inChannel, 0, copyOneSize);
postion = postion + realCopySize;
}
inChannel.transferTo(0, srcFile.length(), outChannel);
} finally {
closeStream(fileInputStream, fileOutputStream);
}
}
}
/***
* 内存映射文件操作
*
* @author 陈波
*
*/
static final class CopyFileMappedByteBuffer extends BaseCopyFile {
@Override
protected void copyFile(String src, String dest) throws IOException {
// 读取文件流
FileChannel srcFile = new RandomAccessFile(src, "r").getChannel();
// 写入文件流,使用读写模式
FileChannel destFile = new RandomAccessFile(dest, "rw").getChannel();
try {
long fileSize = srcFile.size();
// 当前读取文件的位置
long postion = 0;
while (postion < fileSize) {
// 获取本次拷贝文件的长度,
long currentCopySize = Math.min((fileSize - postion), copyOneSize);
// 使用内存映射文件,数据不需要要在JVM进程空间和操作系统Kernal 空间进行拷贝,将destFile映射到底层
MappedByteBuffer mappedByteBuffer = destFile.map(MapMode.READ_WRITE, postion, currentCopySize);
// 从源读取数据直接到映射的目的地
srcFile.read(mappedByteBuffer);
postion = postion + mappedByteBuffer.position();
}
} finally {
closeStream(destFile, srcFile);
}
}
}
}
