几种拷贝文件的实现 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); } } } }