使用java拆分巨大的文本文件来读取它们

时间:2015-10-01 03:40:38

标签: java nio bufferedreader java-io

我正在解析大小超过2Gb的日志文件。要求是将一些预定义的单词与时间戳一起打印到text / csv文件。我写了下面的代码,当使用小块日志文件时它工作正常,但有2GB的实际输入日志文件我出现内存错误。请帮我解决这个问题。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;


    public class MyFileParser{
        private static final String COMMA_STR = ",";
        private static final String NEW_LINE_STR = "\n";


        public static void main(String[] args)  throws IOException{

            String searchString = "" ;
            String line = null;
            boolean searchFlag = false;
            StringBuffer sbr = new StringBuffer();

            FileReader reader = new FileReader("C:\\Users\\Kiran\\Desktop\\mylogs\\File.txt");
            FileWriter writter = new FileWriter("output.csv");
            BufferedReader br = new BufferedReader(reader);


            while( (line = br.readLine())  != null){

                if(line.contains("prompf1") ){
                    searchString= "prompf1";
                    searchFlag = true;
                }

                else if (line.contains("prompf9")){
                    searchString = "prompf9";
                    searchFlag = true;
                }
                    if(searchFlag){
                        String timeStamp = "";
                        int count = 0;
                    char[] charArray =  line.toCharArray();
                    for(int i=0 ; i <= charArray.length ; i++){
            // to remove [] at the begining and ending of time stamp in the file            
                        if(charArray[i] == '[' || charArray[i] == ']'){
                            count ++ ;
                        }
                               else
                        timeStamp= timeStamp+  charArray[i];
                        if(count == 2){
                            break ;
                        }

                    }
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date date = formatter.parse(timeStamp);
                    searchString = date + COMMA_STR+ searchString; 
                    sbr.append(searchString);
                    sbr.append(NEW_LINE_STR);
                    System.out.println(searchString);

                }

            }

            writter.write(sbr.toString());
            writter.flush();
            writter.close();

        }


    }

1 个答案:

答案 0 :(得分:1)

您正在将所有行读入StringBuffer,然后在一次操作中将其写出来。这是不必要的,如果有很多这样的线路会导致内存问题。

你应该做的就是在阅读循环内尽快写下每一行。然后你不需要缓冲任何东西,内存消耗应该大幅下降。

你的代码中实际上还有dateTime = timeStamp+ charArray[i];吗?那不应该是timeStamp = timeStamp+ charArray[i];吗?无论如何,使用String#indexOf()查找[]并使用String#substring()获取日期字符串会更有效。

并且不需要为每一行创建一个新的SimpleDateFormat - 在读取循环之前创建它。