`

各种拆分文件的方式

阅读更多

一:按文件行数拆分

package com.yesky.apachelog.util.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import com.yesky.apachelog.util.regex.ApacheRegexString;

/**
 * 按行读取文件,并按行数对文件进行拆分
 */
public class SeparatorByLine {
	List<String> FilePathArr = new ArrayList<String>();
	String FileName = null;// 原文件名
	long FileSize = 0;// 原文件的大小

	public SeparatorByLine() {
	}

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

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

	/**
	 * 按行写文件
	 * 
	 * @param fileSeparateName:拆分的文件名及路径
	 * @param tempLine:一行的内容
	 * @return
	 */
	private boolean writeFileByLine(String fileSeparateName,
			List<String> tempList)// 往硬盘写文件
	{
		BufferedWriter writer = null;
		try {
			writer = new BufferedWriter(new FileWriter(fileSeparateName, true),
					10 * 1024 * 1024);
			Iterator<String> it = tempList.iterator();
			while (it.hasNext()) {
				String s = (String) it.next(); 
				writer.append(s);
				writer.newLine();
			}
			writer.flush();
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
			return false;

		} finally {
			if (writer != null)
				try {
					writer.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}

		return true;

	}

	/**
	 * 拆分文件,
	 * 
	 * @param fileAndPath
	 * @param currentPath
	 * @param linNum:行数
	 * @return:路径,
	 */
	public List<String> separatorFileByLine(String fileAndPath,
			String currentPath, long linNum)// 折分文件主函数
	{

		List<String> list = new ArrayList<String>();
		getFileAttribute(fileAndPath);// 将文件的名及大小属性取出来
		if (null != currentPath && !("").equals(currentPath)) {
			this.createFolder(currentPath);
		}

		BufferedReader reader = null;
		try {
			reader = new BufferedReader(new FileReader(fileAndPath));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String temp = "";
		int partName = 1;
		String FileCurrentNameAndPath = null;
		try {
			while ((temp = reader.readLine()) != null) {
				
				if (currentPath == null || ("").equals(currentPath))
					FileCurrentNameAndPath = generateSeparatorFileName(
							fileAndPath, partName);
				else
					FileCurrentNameAndPath = generateSeparatorFileName(
							currentPath + FileName, partName);
				temp = temp.replaceAll("\"", "'");
				String regexStr=ApacheRegexString.regexString(temp); 
				if (regexStr != null) {
					list.add(regexStr);
				}

				if (list.size() > 0) {
					if (list.size() % linNum == 0) {
						writeFileByLine(FileCurrentNameAndPath, list);
						FilePathArr.add(FileCurrentNameAndPath);
						partName++;
						list.clear();
					}
				}
			}
			if (list != null && list.size() > 0) {
				writeFileByLine(FileCurrentNameAndPath, list);
				FilePathArr.add(FileCurrentNameAndPath);
				list.clear();
			}
			reader.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null)
				try {
					reader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}

		return FilePathArr;
	}

	/**
	 * 新建目录
	 * 
	 * @param folderPath
	 *            目录
	 * @return 返回目录创建后的路径
	 */
	public void createFolder(String folderPath) {
		String path = folderPath;
		StringTokenizer st = new StringTokenizer(path, "/");
		String path1 = st.nextToken() + "/";
		String path2 = path1;
		while (st.hasMoreTokens()) {
			path1 = st.nextToken() + "/";
			path2 += path1;
			File inbox = new File(path2);
			if (!inbox.exists())
				inbox.mkdir();
		}
	}

	public List<String> getFilePathArr() {
		return FilePathArr;
	}

	public static void main(String[] args) {
		SeparatorByLine separator = new SeparatorByLine();
		String fileAndPath = "e:\\test\\object_access_20091119.log";// 文件名及路径
		long blockSize = 300000000;// 每一个文件块的大小,大小是按字节计算
		Iterator<String> it = separator.separatorFileByLine(fileAndPath, "",
				blockSize).iterator();
		while (it.hasNext()) {
			System.out.println("=====" + it.next());
		}

	}

}

 二:按大小

package com.yesky.util.file;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

/**
 * 文件分隔器:给定文件的路径和每一块要拆分的大小,就可以按要求拆分文件
 * 如果指定的块给原文件都还要大,为了不动原文件,就生成另一个文件,以.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[1024 * 1024 * 10];
		long writeByte = 0;
		int len = 0;
		try {
			raf = new RandomAccessFile(fileAndPath, "r");
			raf.seek(beginPos);
			fos = new FileOutputStream(fileSeparateName);
			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 currentPath:e:/test2/
	 *            拆分后的文件存储路径,可以为null,如果为null或者“”,拆分后的文件和原文件在相同的目录下
	 * @param blockSize
	 *            要拆分的每一块的大小
	 * @return true为拆分成功,false为拆分失败
	 */
	public List<String> separatorFile(String fileAndPath, String currentPath,
			long blockSize)// 折分文件主函数
	{
		List<String> list = new ArrayList<String>();
		getFileAttribute(fileAndPath);// 将文件的名及大小属性取出来
		System.out.println("FileSize:" + FileSize);
		System.out.println("blockSize:" + blockSize);
		BlockNum = getBlockNum(blockSize);// 取得分块总数
		System.out.println("BlockNum:" + BlockNum);
		// System.exit(0);
		if (null != currentPath && !("").equals(currentPath)) {
			System.out.println("创建拆分文件目录");
			this.createFolder(currentPath);
		}

		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) {
				if (currentPath == null || ("").equals(currentPath))
					FileCurrentNameAndPath = fileAndPath + ".bak";
				else
					FileCurrentNameAndPath = currentPath + FileName + ".bak";
			} else {
				if (currentPath == null || ("").equals(currentPath))

					FileCurrentNameAndPath = generateSeparatorFileName(
							fileAndPath, i);

				else
					FileCurrentNameAndPath = generateSeparatorFileName(
							currentPath + FileName, i);
			}
			System.out.print("本次写入:" + writeSize);
			System.out.println("拆分后的文件路径==" + FileCurrentNameAndPath);

			// System.exit(0);
			writeFile(fileAndPath, FileCurrentNameAndPath, writeSize,
					writeTotal);// 循环往硬盘写文件
			// 把拆分文件地址存入list
			list.add(FileCurrentNameAndPath);
			writeTotal = writeTotal + writeSize;
			System.out.println(" 总共写入:" + writeTotal);
		}
		return list;
	}

	/**
	 * 新建目录
	 * 
	 * @param folderPath
	 *            目录
	 * @return 返回目录创建后的路径
	 */
	public void createFolder(String folderPath) {
		String path = folderPath;
		StringTokenizer st = new StringTokenizer(path, "/");
		String path1 = st.nextToken() + "/";
		String path2 = path1;
		while (st.hasMoreTokens()) {
			path1 = st.nextToken() + "/";
			path2 += path1;
			File inbox = new File(path2);
			if (!inbox.exists())
				inbox.mkdir();
		}
	}

	public static void main(String[] args) {
		Separator separator = new Separator();
		String fileAndPath = "e:\\catalina.out";// 文件名及路径
		long blockSize = 1024 * 1024 * 50;// 每一个文件块的大小,大小是按字节计算
		List l = separator.separatorFile(fileAndPath, "", blockSize);

		Iterator it = l.iterator();
		while (it.hasNext()) {
			System.out.println("=====" + it.next());
		}

	}

}

 文件合并

package com.yesky.util.file;

/**
 * 合并文件:合并由拆分文件拆分的文件
 * 要求将拆分文件放到一个文件夹中
 * 主要利用随机文件读取和文件输入输出流
 */
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

import java.util.Arrays;
import java.util.StringTokenizer;

public class Combination {
	String srcDirectory = null;// 拆分文件存放的目录
	String[] separatedFiles;// 存放所有拆分文件名
	String[][] separatedFilesAndSize;// 存放所有拆分文件名及分件大小
	int FileNum = 0;// 确定文件个数
	String fileRealName = "";// 据拆分文件名确定现在原文件名

	public Combination() {
		srcDirectory = "e:\\test\\";
	}

	/**
	 * 
	 * @param sFileName
	 *            任一一个拆分文件名
	 * @return 原文件名
	 */
	private String getRealName(String sFileName) {
		StringTokenizer st = new StringTokenizer(sFileName, ".");
		return st.nextToken() + "." + st.nextToken();
	}

	/**
	 * 取得指定拆分文件模块的文件大小
	 * 
	 * @param FileName
	 *            拆分的文件名
	 * @return
	 */
	private long getFileSize(String FileName) {
		FileName = srcDirectory + FileName;
		return (new File(FileName).length());
	}

	/**
	 * 生成一些属性,做初使化
	 * 
	 * @param drictory
	 *            拆分文件目录
	 */
	private void getFileAttribute(String drictory) {
		File file = new File(drictory);
		separatedFiles = new String[file.list().length];// 依文件数目动态生成一维数组,只有文件名
		separatedFiles = file.list();
		// 依文件数目动态生成二维数组,包括文件名和文件大小
		// 第一维装文件名,第二维为该文件的字节大小
		separatedFilesAndSize = new String[separatedFiles.length][2];
		Arrays.sort(separatedFiles);// 排序
		FileNum = separatedFiles.length;// 当前文件夹下面有多少个文件
		for (int i = 0; i < FileNum; i++) {
			separatedFilesAndSize[i][0] = separatedFiles[i];// 文件名
			separatedFilesAndSize[i][1] = String
					.valueOf(getFileSize(separatedFiles[i]));// 文件大上
		}
		fileRealName = getRealName(separatedFiles[FileNum - 1]);// 取得文件分隔前的原文件名
	}

	/**
	 * 合并文件:利用随机文件读写
	 * 
	 * @return true为成功合并文件
	 */
	private boolean CombFile() {
		RandomAccessFile raf = null;
		long alreadyWrite = 0;
		FileInputStream fis = null;
		int len = 0;
		byte[] bt = new byte[1024];
		try {
			raf = new RandomAccessFile(srcDirectory + fileRealName, "rw");
			for (int i = 0; i < FileNum; i++) {
				raf.seek(alreadyWrite);
				fis = new FileInputStream(srcDirectory
						+ separatedFilesAndSize[i][0]);
				while ((len = fis.read(bt)) > 0) {
					raf.write(bt, 0, len);
				}
				fis.close();
				alreadyWrite = alreadyWrite
						+ Long.parseLong(separatedFilesAndSize[i][1]);
			}
			raf.close();
		} catch (Exception e) {
			e.printStackTrace();
			try {
				if (raf != null)
					raf.close();
				if (fis != null)
					fis.close();
			} catch (IOException f) {
				f.printStackTrace();
			}
			return false;
		}
		return true;
	}

	public static void main(String[] args) {
		Combination combination = new Combination();
		combination.getFileAttribute(combination.srcDirectory);
		combination.CombFile();
		System.exit(0);
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics