当前位置 : 主页 > 编程语言 > java >

CopyFileUtils

来源:互联网 收集:自由互联 发布时间:2021-06-28
几种拷贝文件的实现 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);
			}
		}

	}

}
网友评论