从大文件中提取模式的更多性能方法是什么(超过700MB)

时间:2012-11-29 19:09:32

标签: java performance parsing large-files

我遇到了一个问题,需要我从本地机器解析一个文本文件。有一些并发症:

  1. 文件可能非常大(700mb +)
  2. 模式以多行显示
  3. 我需要在模式之后的商店线信息
  4. 我使用BufferReaderString.indexOfString.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 ( ... ) {
        ...
    }
    

4 个答案:

答案 0 :(得分:2)

您的此代码非常可疑,可能至少会导致您的性能问题的一部分:

FileInputStream f1 = new FileInputStream("c:\\Temp\\fo1.txt");
DataInputStream in = new DataInputStream(f1);
BufferedReader br = new BufferedReader(new InputStreamReader(in));

您没有充分理由涉及DataInputStream,实际上将其用作Reader的输入可视为代码损坏的情况。写下这个:

InputStream f1 = new FileInputStream("c:\\Temp\\fo1.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fr));

对性能的巨大损害是您正在使用的System.out,尤其是在Eclipse中运行时测量性能,但即使从命令行运行也是如此。我的猜测是,这是造成瓶颈的主要原因。无论如何,确保在瞄准最佳性能时不要在主循环中打印任何内容。

答案 1 :(得分:1)

除了Marko的回答之外,我建议关闭br,而不是f1:

br.close()

这不会影响性能,但更清洁。 (关闭最外面的流)

答案 2 :(得分:0)

查看java.util.regex

来自oracle的优秀tutorial

来自JAVADoc的复制粘贴:

  

用于将字符序列与正则表达式指定的模式匹配的类。

     

Pattern类的实例表示以字符串形式指定的正则表达式,其语法类似于Perl使用的语法。

     

Matcher类的实例用于匹配给定模式的字符序列。输入通过CharSequence接口提供给匹配器,以支持匹配来自各种输入源的字符。

     

除非另有说明,否则将null参数传递给此包中任何类或接口中的方法都将导致抛出NullPointerException。

答案 3 :(得分:0)

完美无缺!!

我跟随 OldCurmudgeon Marko Topolnik AlexWien 建议,我的表现提升了1000%。在程序花了2个小时完成所描述的操作并在文件中写入响应之前。 现在它花了5分钟!!并且SYSO保留在源代码中!!

我认为改进的原因是改变字符串“源”,就像OldCurmudgeon建议的HashSet“源”一样。 Bur我删除了DataInputStream并使用了“br.close”。

谢谢你们!