一:按文件行数拆分
- 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);
- }
- }