使用java拆分巨大的文本文件以读取它们
我正在解析一个大于2Gb的日志文件。要求将一些预定义的单词以及时间戳打印到文本/csv文件中。我已经写了下面的代码,当使用一小段日志文件时,它可以正常工作,但是使用2GB的实际输入日志文件时,我遇到了内存不足的错误。请帮我解决这个问题使用java拆分巨大的文本文件以读取它们,java,nio,bufferedreader,java-io,Java,Nio,Bufferedreader,Java Io,我正在解析一个大于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.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.io.BufferedReader;
导入java.io.FileReader;
导入java.io.FileWriter;
导入java.sql.Time;
导入java.sql.Timestamp;
导入java.text.simpleDataFormat;
导入java.util.Date;
公共类MyFileParser{
私有静态最终字符串逗号_STR=“,”;
私有静态最终字符串NEW\u LINE\u STR=“\n”;
公共静态void main(字符串[]args)引发IOException{
字符串searchString=“”;
字符串行=null;
布尔searchFlag=false;
StringBuffer sbr=新的StringBuffer();
FileReader=newFileReader(“C:\\Users\\Kiran\\Desktop\\mylogs\\File.txt”);
FileWriter writer=新的FileWriter(“output.csv”);
BufferedReader br=新的BufferedReader(读卡器);
而((line=br.readLine())!=null){
if(第行包含(“prompf1”)){
searchString=“prompf1”;
searchFlag=true;
}
else if(第行包含(“prompf9”)){
searchString=“prompf9”;
searchFlag=true;
}
如果(搜索标志){
字符串时间戳=”;
整数计数=0;
char[]charArray=line.toCharArray();
对于(int i=0;i您正在将所有行读取到一个StringBuffer
中,然后在一次操作中将它们写出来。这是不必要的,如果有许多这样的行,将导致内存问题
你应该做的是在读循环中写下每一行,这样你就不需要缓冲任何东西,内存消耗也会急剧下降
另外,您的代码中是否真的有dateTime=timeStamp+charArray[i];
?这不应该是timeStamp=timeStamp+charArray[i];
?无论如何,使用查找[
和]
并获取日期字符串会更有效
无需为每一行创建一个新的SimpleDateFormat
——在读取循环之前创建它。是的,你是对的。那一行应该是timeStamp=timeStamp+charArray[i];我将根据您的评论修改代码。但我仍然不确定这些更改是否会处理内存不足错误…有没有办法将它们拆分为临时文件并读取?@kiran如果您需要一次将其全部读取到内存中,则拆分该文件会有所帮助。但如果您逐行读取并写入所需的行,则无需执行此操作立即选择,而不将它们添加到StringBuffer
。好的,让我用修改后的更改测试代码。如果遇到任何问题,我将在此处发布更新。再次感谢