Java 从大文件(超过700MB)中提取模式的更有效的方法是什么
我遇到一个问题,需要从本地计算机解析文本文件。有一些复杂情况:Java 从大文件(超过700MB)中提取模式的更有效的方法是什么,java,performance,parsing,large-files,Java,Performance,Parsing,Large Files,我遇到一个问题,需要从本地计算机解析文本文件。有一些复杂情况: 文件可能相当大(700mb+) 该模式出现在多行中 我需要在模式之后存储行信息 我使用BufferReader、String.indexOf和String.substring(获取第3项)创建了一个简单的代码 文件中有一个名为code=的键(模式),它在不同的块中多次出现。程序使用BufferReader.readLine从该文件中读取每一行。它使用indexOf检查模式是否出现,然后在模式后提取文本并存储在公共字符串中 当我用60
BufferReader
、String.indexOf
和String.substring
(获取第3项)创建了一个简单的代码
文件中有一个名为code=
的键(模式),它在不同的块中多次出现。程序使用BufferReader.readLine
从该文件中读取每一行。它使用indexOf
检查模式是否出现,然后在模式后提取文本并存储在公共字符串中
当我用600mb文件运行我的程序时,我注意到它处理文件时性能最差。我在CodeRanch上读到一篇文章说,Scanner
类不适合大文件
是否有一些技术或库可以提高我的性能
提前谢谢
以下是我的源代码:
String codeC = "code=[";
String source = "";
try {
FileInputStream f1 = new FileInputStream("c:\\Temp\\fo1.txt");
DataInputStream in = new DataInputStream(f1);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
boolean bPrnt = false;
int ln = 0;
// Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
if (strLine.indexOf(codeC) != -1) {
ln++;
System.out.println(strLine + " ---- register : " + ln);
strLine = strLine.substring(codeC.length(), strLine.length());
source = source + "\n" + strLine;
}
}
System.out.println("");
System.out.println("Lines :" + ln);
f1.close();
} catch ( ... ) {
...
}
看看
来自甲骨文的一篇优秀的文章
来自JAVADoc的复制粘贴:
用于根据正则表达式指定的模式匹配字符序列的类
模式类的一个实例表示一个正则表达式,该正则表达式以字符串形式指定,语法与Perl使用的语法类似
Matcher类的实例用于根据给定模式匹配字符序列。输入通过CharSequence接口提供给匹配器,以支持对来自各种输入源的字符进行匹配
除非另有说明,否则将null参数传递给此包中任何类或接口中的方法将导致引发NullPointerException
您的这段代码非常可疑,可能至少是您性能问题的一部分原因:
FileInputStream f1 = new FileInputStream("c:\\Temp\\fo1.txt");
DataInputStream in = new DataInputStream(f1);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
您无缘无故地涉及到DataInputStream
,事实上,将其用作读取器的输入可以被视为代码中断的情况。写下以下内容:
InputStream f1 = new FileInputStream("c:\\Temp\\fo1.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fr));
对性能的一个巨大损害是您正在使用的System.out
,尤其是在Eclipse中运行时测量性能,但即使是从命令行运行。我猜,这是造成瓶颈的主要原因。在您为最高性能而设定目标时,请确保您在主循环中不会打印任何内容。除了Marko回答的内容外,我建议关闭br,而不是f1:
br.close()
这不会影响性能,但更干净。(关闭最外面的流)它工作得非常好
我遵循了OldCurmudgeon、Marko Topolnik和AlexWien的建议,我的表现提高了1000%。之前,程序花了2个小时来完成所描述的操作并在文件中写入响应。
现在它花了5分钟!!而SYSO仍保留在源代码中
我认为巨大改进的原因是像OldCurmudgeon建议的那样,将字符串“source”更改为哈希集“source”。但是我删除了DataInputStream并使用了“br.close”
谢谢大家 我的意思是,他正在链中插入一个DataInputStream
。这是不需要的。读者部分还可以。他是否应该更好地使用br.close()而不是f1.close()?使用br.close()
,这会更习惯,是的,但不会影响性能和系统资源(打开的文件)将以任何方式发布。除了下面@Marko所建议的内容之外,我建议您在StringBuilder中收集结果,或者最好是在列表中收集结果。将其构建为一个潜在的巨大字符串可能会极大地影响内存占用。我认为最大的改进是删除System.out.prinltn()。