java使用stream流批量读取并合并文件,避免File相关类导致单文件过大造成的内存溢出。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

public class MergeFileByStream {

    /** 跨平台的换行符  */
    public static final String LINE_SEPARATOR = System.getProperty("line.separator");
    
    /**
     * 合并文件  outFileName为路径+文件名
     * @Method       mergeFiles
     * @Description  TODO
     * @Author           LBH
     * @Date         2015-3-23 下午4:26:54
     * @param        
     * @return       boolean
     */
    public boolean mergeFiles(String outFileName, Set<String> files) {

        boolean mergeResule = false;// 结果
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        String inputEncoding = "UTF-8";
        try {
            // 验证是否已存在输出文件,存在就删除
            File outFile = new File(outFileName);
            if (outFile.exists()) {
                outFile.delete();
            }

            int i = 0;// 循环计数
            Iterator<String> filesIt = files.iterator();

            if (filesIt != null && files.size() > 1) {
                File inFile = new File(filesIt.next());
                inputStreamReader = new InputStreamReader(new FileInputStream(
                        inFile), inputEncoding);
                bufferedReader = new BufferedReader(inputStreamReader);

                // 开始处理文件
                if (bufferedReader != null && bufferedReader.ready()) {
                    if (i == 0) { // 如果是首个文件,那么除去最后一行保留前两行再写入
                        mergeResule = handleFile("fist", bufferedReader,outFileName, inputEncoding);
                    } else if (i == files.size() - 1) { // 如果是最后一个文件,那么去除前两行,保留最后一行
                        mergeResule = handleFile("last", bufferedReader,outFileName, inputEncoding);
                    } else { // 其他则同时去除前两行和最后一行
                        mergeResule = handleFile("normal", bufferedReader,outFileName, inputEncoding);
                    }
                }
                // 删除该文件
                inFile.delete();
                i++;
            } else if (filesIt != null && files.size() == 1) {// 若只有一个文件,那么直接改名字
                File inFile = new File(filesIt.next());
                inFile.renameTo(new File(outFileName));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 关闭
        finally {
            if (bufferedReader != null) {
                try {bufferedReader.close();} catch (Exception e) {e.printStackTrace();}
                }
            if (inputStreamReader != null) {
                try {inputStreamReader.close();} catch (Exception e) {e.printStackTrace();
                }
            }
        }
        return mergeResule;
    }

    /**
     * 处理单个文件,读取后立即写入, type:fist--首个文件;last--末个文件;以及其他文件
     * 
     * @Method handleFile
     * @Author lbh
     * @Date 2014-12-11 上午09:49:19
     */
    public static boolean handleFile(String type, BufferedReader bufferedReader, String outFile, String outEncoding) {
        boolean handleResult = false; // 是否成功
        FileOutputStream fileOutputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        String readString = ""; // 存放读取数据的变量
        String strA, strB, strC; // 临时变量
        try {
            fileOutputStream = new FileOutputStream(outFile, true);
            outputStreamWriter = new OutputStreamWriter(fileOutputStream, outEncoding);
            
            if ("fist".equals(type)) { // 首文件的处理
                strA = "";
                strB = "";
                strC = "";
                int fistI = 0;// 计数
                while ((strC = bufferedReader.readLine()) != null) { // 从第一行开始循环读
                    strA = strB;
                    strB = strC;
                    readString = strA + LINE_SEPARATOR;// 最后一行的strB被丢弃
                    // 输出
                    if (fistI > 0) {// 避免第一行空行
                        outputStreamWriter.write(readString);
                        outputStreamWriter.flush();
                    }
                    fistI++;
                }
                handleResult = true;
            }
            if ("last".equals(type)) { // 末文件的处理
                strA = "";
                bufferedReader.readLine();
                bufferedReader.readLine(); // 执行两次,已读取并丢弃了前两行。
                while ((strA = bufferedReader.readLine()) != null) { // 开始循环读
                    readString = strA + LINE_SEPARATOR;

                    // 输出
                    outputStreamWriter.write(readString);
                    outputStreamWriter.flush();
                }
                handleResult = true;
            } else { // 其他文件的处理
                strA = "";
                strB = "";
                strC = "";
                bufferedReader.readLine();
                bufferedReader.readLine(); // 执行两次,已读取并丢弃了前两行。
                long i = 0;
                while ((strC = bufferedReader.readLine()) != null) { // 开始循环读
                    strA = strB;
                    strB = strC;
                    readString = strA + LINE_SEPARATOR;// 最后一行的strB被丢弃

                    // 输出
                    if (i > 0) {// 避免第一行空行
                        outputStreamWriter.write(readString);
                        outputStreamWriter.flush();
                    }
                    i++;
                }
                handleResult = true;
            }
        } catch (IOException e) {e.printStackTrace();} 
        
        // 关闭
        finally {
            if (fileOutputStream != null) {
                try {fileOutputStream.close();} catch (Exception e) {e.printStackTrace();}
                }
            if (outputStreamWriter != null) {
                try {outputStreamWriter.close();} catch (Exception e) {e.printStackTrace();
                }
            }
        }
        return handleResult;
    }

     public static void main(String[] args) throws Exception{
            System.out.println("开始");
            Set<String> ssss = new LinkedHashSet<String>();
            ssss.add("E:\\111\\xmlTest\\a.xml");
            ssss.add("E:\\111\\xmlTest\\b.xml");
            ssss.add("E:\\111\\xmlTest\\c.xml");
            MergeFileByStream st = new MergeFileByStream();
            st.mergeFiles("E:\\111\\xmlTest\\stream2.xml", ssss);
            System.out.println("结束");
        }
}

 

posted @ 2015-03-12 13:56  好人卡收藏家  阅读(1109)  评论(0编辑  收藏  举报