合并文件

 1. 拆分
import java.io.File;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Date;

/**
 * 文件分隔器:给定文件的路径和每一块要拆分的大小,就可以按要求拆分文件
 * 如果指定的块给原文件都还要大,为了不动原文件,就生成另一个文件,以.bak为后缀,这样可以保证原文件
 * 如果是程序自动拆分为多个文件,那么后缀分别为".part序号",这样就可以方便文件的合并了 原理:很简单,就是利用是输入输出流,加上随机文件读取。
 */
public class Separator {
	String FileName = null;// 原文件名

	long FileSize = 0;// 原文件的大小

	long BlockNum = 0;// 可分的块数

	public Separator() {
	}

	/**
	 * 
	 * @param fileAndPath
	 *            原文件名及路径
	 */
	private void getFileAttribute(String fileAndPath)// 取得原文件的属性
	{
		File file = new File(fileAndPath);
		FileName = file.getName();
		FileSize = file.length();
	}

	/**
	 * 
	 * @param blockSize
	 *            每一块的大小
	 * @return 能够分得的块数
	 */
	private long getBlockNum(long blockSize)// 取得分块数
	{
		long fileSize = FileSize;
		if (fileSize <= blockSize)// 如果分块的小小只够分一个块
			return 1;
		else {
			if (fileSize % blockSize > 0) {
				return fileSize / blockSize + 1;
			} else
				return fileSize / blockSize;
		}
	}

	/**
	 * 
	 * @param fileAndPath
	 *            原文件及完整路径
	 * @param currentBlock
	 *            当前块的序号
	 * @return 现在拆分后块的文件名
	 */
	private String generateSeparatorFileName(String fileAndPath,
			int currentBlock)// 生成折分后的文件名,以便于将来合将
	{
		return fileAndPath + ".part" + currentBlock;
	}

	/**
	 * 
	 * @param fileAndPath
	 *            原文件及完整路径
	 * @param fileSeparateName
	 *            文件分隔后要生成的文件名,与原文件在同一个目录下
	 * @param blockSize
	 *            当前块要写的字节数
	 * @param beginPos
	 *            从原文件的什么地方开始读取
	 * @return true为写入成功,false为写入失败
	 */
	private boolean writeFile(String fileAndPath, String fileSeparateName,
			long blockSize, long beginPos)// 往硬盘写文件
	{

		RandomAccessFile raf = null;
		FileOutputStream fos = null;
		byte[] bt = new byte[10*1024*1024];
		long writeByte = 0;
		int len = 0;
		try {
			raf = new RandomAccessFile(fileAndPath, "r");
			fos = new FileOutputStream(fileSeparateName);
			
			MappedByteBuffer buf = raf.getChannel().map(FileChannel.MapMode.READ_ONLY, beginPos, blockSize);  
			fos.getChannel().write(buf);
//			raf.seek(beginPos);
//			while ((len = raf.read(bt)) > 0) {
//				if (writeByte < blockSize)// 如果当前块还没有写满
//				{
//					writeByte = writeByte + len;
//					if (writeByte <= blockSize)
//						fos.write(bt, 0, len);
//					else {
//						len = len - (int) (writeByte - blockSize);
//						fos.write(bt, 0, len);
//					}
//				}
//			}
			fos.close();
			raf.close();
		} catch (Exception e) {
			e.printStackTrace();
			try {
				if (fos != null)
					fos.close();
				if (raf != null)
					raf.close();
			} catch (Exception f) {
				f.printStackTrace();
			}
			return false;
		}
		return true;
	}

	/**
	 * 
	 * @param fileAndPath
	 *            原文路径及文件名
	 * @param blockSize
	 *            要拆分的每一块的大小
	 * @return true为拆分成功,false为拆分失败
	 */
	private boolean separatorFile(String fileAndPath, long blockSize)// 折分文件主函数
	{
		getFileAttribute(fileAndPath);// 将文件的名及大小属性取出来
		// System.out.println("FileSize:"+FileSize);
		// System.out.println("blockSize:"+blockSize);
		BlockNum = getBlockNum(blockSize);// 取得分块总数
		// System.out.println("BlockNum:"+BlockNum);
		// System.exit(0);
		if (BlockNum == 1)// 如果只能够分一块,就一次性写入
			blockSize = FileSize;
		long writeSize = 0;// 每次写入的字节
		long writeTotal = 0;// 已经写了的字节
		String FileCurrentNameAndPath = null;
		for (int i = 1; i <= BlockNum; i++) {
			if (i < BlockNum)
				writeSize = blockSize;// 取得每一次要写入的文件大小
			else
				writeSize = FileSize - writeTotal;
			if (BlockNum == 1)
				FileCurrentNameAndPath = fileAndPath + ".bak";
			else
				FileCurrentNameAndPath = generateSeparatorFileName(fileAndPath,
						i);
			// System.out.print("本次写入:"+writeSize);
			if (!writeFile(fileAndPath, FileCurrentNameAndPath, writeSize,
					writeTotal))// 循环往硬盘写文件
				return false;
			writeTotal = writeTotal + writeSize;
			// System.out.println(" 总共写入:"+writeTotal);
		}
		return true;
	}
  
	public static void main(String[] args) {
		
		Separator separator = new Separator();
		String fileAndPath = "f:\\test2\\123.zip";// 文件名及路径
		long blockSize = 10*1024 * 1024;// 每一个文件块的大小,大小是按字节计算
		if (separator.separatorFile(fileAndPath, blockSize)) {
			System.out.println("文件折分成功!");
		} else {
			System.out.println("文件折分失败!");
		}
			}
}

你可能感兴趣的:(F#)