解析文本文件:效率和性能

时间:2013-03-13 20:12:09

标签: java parsing etl

我正处于与解析文本文件相关的小型开发项目中(应用ETL方法)。我创建了一个在我的本地机器上正确运行的演示代码,但是当我将它部署到Apache Tomcat容器时,会产生很多与内存溢出,类型转换等相关的错误。

这是一般事实:

这是file structure(注释指定每个单元格的数据类型和其他相关信息)。

请注意 RegisterType1 每位客户只能重复一次, RegisterType2 可能会重复一次或多次, RegisterType3 RegisterType4 重复一次。

另请注意,每种寄存器类型的长度不同,即:RegisterType1 12个字段,RegisterType2 10个字段,依此类推。

正如我之前所说,我当前的解析器编码错误,导致产生大量错误。 This is the actual codethis one(创建数据库连接和执行查询的类)。

这是一个需要解析的example text file

当前的开发环境 平台:Java 6 容器:Tomcat 7 VPS配置文件:RAM 1.7GB,存储容量:20GB,处理器:(英特尔(R)Xeon(R)CPU X5650 @ 2.67GHz,24核)。

实际问题:

  • 性能不佳
  • 内存溢出
  • 解析错误:数据类型转换,字段之间的分隔符(分号)(例如:... Paris; Fran [这里是分号] ce; ...)

我想创建一个高效,正确且高性能的解析器。

我需要一些关于这个主题的建议。哪个是创建好解析器的最佳方法?

提前感谢您的信息。

此致

1 个答案:

答案 0 :(得分:1)

在此处发布您的相关代码。好的,我会为你做一些事情:

    BufferedReader reader = null;

    ArrayList< String> elements = new ArrayList< String>();

    try {
        reader = new BufferedReader(new FileReader(archivoFuenteDatos));
        String text = null;

        // repeat until all lines is read
        while ((text = reader.readLine()) != null) {
        ...
        elements.add(...);
        ...
    } catch(...) ...

    saveOnDB(elements);

不要读那样的大文件。如果你这样做,你必须同时将所有数据保存在内存中。

  1. 尝试将每个条目直接写入数据库,而不是先复制到数组列表。这有望解决OOM问题。

  2. 描述您的代码。如果它足够快,你就完成了。

  3. 如果速度不够快,请创建一个ArrayList。给它一个初始容量n。在写入数据库之前,不要将n个项目读入该列表。

  4. 编辑: 如果我没有错过重要的东西,你复制了自己的代码4次。请在发布前重构(代码太多)。例如,巨大的开关可以重构为这样的东西:

            while ((text = reader.readLine()) != null) {
                String[] campos = text.replaceAll(" +", " ").split(";");
                int n;
                switch (text.charAt(0)) {
                    case '1':
                    case '2':
                    case '3':
                        n = campos.length - 1;
                        break;
                    case '4':
                        // what does this mean? It will always give 5!
                        // n = contarPuntoComas(text) == 6 ? 5 : 5;
                        n = 5;
                        break;
                    default:
                        n= 0;
                }
                for (int i = 0; i < n; ++i) {
                     elements.add(campos[ i].trim());
                } // end for
            }