我正在解析大小超过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();
}
}
答案 0 :(得分:1)
您正在将所有行读入StringBuffer
,然后在一次操作中将其写出来。这是不必要的,如果有很多这样的线路会导致内存问题。
你应该做的就是在阅读循环内尽快写下每一行。然后你不需要缓冲任何东西,内存消耗应该大幅下降。
你的代码中实际上还有dateTime = timeStamp+ charArray[i];
吗?那不应该是timeStamp = timeStamp+ charArray[i];
吗?无论如何,使用String#indexOf()
查找[
和]
并使用String#substring()
获取日期字符串会更有效。
并且不需要为每一行创建一个新的SimpleDateFormat
- 在读取循环之前创建它。