`

各种拆分文件的方式

阅读更多

一:按文件行数拆分

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);
	}
}

 

分享到:
评论

相关推荐

    EXCEL 拆分工作薄 拆分文件 合并文件

    EXCEL 按列拆分工作薄 拆分文件 合并文件 程序没写死 不影响功能。出错请关了重开。

    SQLDumpSplitter 大Sql文件拆分成小文件

    SQLDumpSplitter的工作原理是解析SQL语句的结构,根据特定规则(如每N行、每个事务、每个CREATE TABLE语句等)来拆分文件。这样,用户可以设置合适的拆分条件,确保新生成的小文件在逻辑上是完整和可执行的。例如,...

    文本文件按行拆分多个成文件

    - Linux/Unix命令行:`split`命令可以根据行数或大小拆分文件。 - Windows批处理:可以通过`for /F`循环和`more`命令实现拆分。 四、实际操作步骤 1. 打开终端或命令提示符。 2. 导航到大文件所在目录。 3. 使用...

    SQL大文件拆分工具SQLDumpSplitter

    4. **文件分割**:在选定的拆分点将文件分割成多个小文件,每个文件包含一部分数据或表定义。 5. **保存和命名**:将拆分后的文件保存,并通常按照原文件名加上编号或其他标识进行命名,以便于用户后续识别和操作。 ...

    CSV表格拆分,可以把一个CSV文件按固定行数拆分成多个文件

    本教程将详细解释如何通过特定工具或编程方式实现CSV表格的拆分。 ### CSV文件的特点 1. **易读性**:由于CSV是纯文本格式,可以用任何文本编辑器打开,方便查看。 2. **跨平台**:CSV文件不受操作系统限制,可以在...

    python脚本拆分bin文件

    python脚本拆分bin文件

    PDF文件拆分工具

    6. **兼容性**:好的PDF拆分工具应支持不同版本的PDF文件,并能保证拆分后的文件在各种操作系统和PDF阅读器上都能正常打开和阅读。 7. **批量处理**:对于需要处理大量PDF文件的情况,某些工具提供了批量拆分功能,...

    拆分与合并文件

    4. 文件完整性:在拆分文件前,备份原始文件以防意外,同时在合并后检查文件是否完整无误。 对于压缩包中的"拆分与合并文件",这可能包含了一系列用于演示或教学的音频文件,通过这些文件,用户可以亲手实践文件的...

    大文件拆分

    1. **网络传输**:大型文件在网络上传输时可能会遇到带宽限制,拆分文件可以分批传输,减少单次传输的压力。 2. **存储限制**:某些存储系统可能对单个文件的大小有限制,拆分文件可以绕过这些限制。 3. **分发和...

    用于虚拟筛选批量拆分sdf文件

    将sdf文件拆分为单个pdb文件

    windows批处理-批处理按指定行数拆分文本文件的脚本

    本案例中的批处理脚本主要用于按指定的行数拆分文本文件,这对于管理和分析大型日志文件尤其有用。下面我们将详细探讨这个脚本的工作原理及其相关知识点。 批处理脚本的创建通常使用记事本(Notepad)或其他文本...

    c++调用python接口实现压缩拆分文件功能

    在本项目中,Python编写了压缩和拆分文件的逻辑,然后通过`ctypes`库或其他类似的库(如`pybind11`)暴露这些功能给C++。`ctypes`是Python的内置库,可以直接调用C等级别的动态链接库(DLLs或SOs),而`pybind11`则...

    C#拆分和合并文件例程

    本示例主要关注的是文件的拆分和合并功能,这对于处理大型文件或者优化数据传输过程尤为关键。以下将详细阐述C#中实现文件拆分和合并的基本原理及步骤。 1. **文件拆分** 文件拆分是指将一个大文件分割成多个小...

    文件拆分与合并

    在IT领域,文件拆分与合并是一项常见的操作,特别是在处理大型文件时,为了方便传输、存储或管理,我们可能需要将大文件分割成若干小文件,之后再将这些小文件合并回原始文件。在这个场景中,`vc6.0`(Visual C++ ...

    按行拆分TXT文件成多个TXT集合(SplitFile)

    5. **操作方式**:了解工具是通过拖放文件、浏览选择,还是在命令行中输入参数进行操作。 了解这些基本信息后,用户可以根据自身需求调整参数,高效地对大文件进行拆分。在实际应用中,这样的工具还能结合批处理...

    用C#做的拆分文件器

    本项目“用C#做的拆分文件器”是利用C#编写的工具,其主要功能是对大型文件进行拆分,以便于存储、传输或者在资源有限的环境中处理。下面将详细阐述C#语言在文件操作方面的知识,以及如何实现文件拆分功能。 首先,...

    CSV 快速拆分工具

    1. **按行数拆分**:用户可以设置每份拆分文件包含的行数,比如每1000行创建一个新的CSV文件。 2. **按大小拆分**:根据文件大小进行拆分,例如限制每个拆分文件不超过1MB或5MB。 3. **按列值拆分**:根据特定列的...

    csv文件拆分或者转excel工具

    1. CSV文件拆分:将一个大的CSV文件拆分成多个小的CSV文件,每个文件包含不超过100万行的数据。(默认设计是超过100行数据拆分) 2. CSV转Excel:将CSV文件转换为Excel文件,同时处理可能的乱码和科学计数法问题。

    FLASH文件拆分工具SWFQuicker

    总之,SWFQuicker是一款强大的SWF文件拆分工具,为用户提供了一种便捷的方式去探索和利用SWF文件的内部结构。无论你是开发者、设计师还是教育工作者,都可以根据需求灵活运用它,提升工作效率。

    android文件的合并与拆分

    这种方式适用于小文件,大文件可能需要考虑内存限制。 2. XML文件合并:XML文件可能包含资源信息,如布局、字符串等。使用DOM解析器,可以加载所有XML文件到一个Document对象中,然后将它们合并成一个新的XML文件。...

Global site tag (gtag.js) - Google Analytics