【问题标题】:Split huge text files using java to Read them使用java拆分巨大的文本文件以读取它们
【发布时间】:2015-10-01 03:40:38
【问题描述】:

我正在解析大小超过 2Gb 的日志文件。要求是将一些预定义的单词连同时间戳一起打印到文本/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();

        }


    }

【问题讨论】:

    标签: java nio bufferedreader java-io


    【解决方案1】:

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

    您应该做的是在读取循环中写入每一行。这样你就不需要缓冲任何东西了,内存消耗应该会急剧下降。

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

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

    【讨论】:

    • 是的,你是对的..那行应该是 timeStamp = timeStamp+ charArray[i];我将根据您的 cmets 修改代码。但是我仍然不确定这些更改是否会处理内存不足错误...有没有办法将它们拆分为临时文件并读取?
    • @kiran 如果您需要一次将文件全部读入内存,拆分文件会有所帮助。但是,如果您逐行阅读并立即编写您选择的行而不将它们添加到StringBuffer中,则不需要这样做。
    • 好的,让我测试修改后的代码。如果我遇到任何问题,我会在这里发布更新。再次感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    相关资源
    最近更新 更多