解析大文件的问题

时间:2011-03-28 16:09:09

标签: java parsing

我正在解析文档并写入磁盘对,例如:

0 vs 1, true
0 vs 2, false
0 vs 3, true
1 vs 2, true
1 vs 3, false
..

等等。

接下来我通过删除随机行(如果它们超出的值具有真值,并且反之亦然)来平衡每个实例的trues和falses行,并且我最终得到一个像这样的文件:

0 vs 1 true
0 vs 2 false
1 vs 2 true
1 vs 3 true
1 vs 4 false
1 vs 5 false

这些谬误通常远远超过真实,所以在前面的例子中,我只能为isntance 0保留1个假,而对于1个实例只有2个falses。

在解析然后平衡之前,我分两个步骤完成此过程。

现在,我的问题是不平衡文件太大:超过1GB,其大部分行将通过平衡步骤删除。

我的问题是:我可以在解析时平衡行吗?

我的猜测是否定的,因为我不知道哪些项目到达,并且在找到特定实例的所有行之前我无法删除任何行。

我希望很清楚。 感谢

3 个答案:

答案 0 :(得分:0)

听起来你只需要一次加载一个实例的数据,你只需要为每个实例值记录一个数字和一个布尔值。

我建议您在实例编号更改(或文件结束)之前读取数据。这应该远远小于1 GB并修复内存。

如果使用TIntArrayList(或int [])和BitSet,这将更有效地存储数据。您可以在处理每个实例后清除它们。

编辑:如果数据是随机排列的,您可能需要读取一次文件以计算每个实例的真/假数,然后再次读取该文件以生成结果。

另一种选择是尝试以不同的方式将整个文件加载到内存中。您应该能够以此格式加载1 GB的数据,并使其使用少于1 GB。

您需要了解如何最大限度地减少每行数据的开销,并且可以显着降低消耗。

class Row { // uses a total of 80 bytes in a 32-bit JVM
    // 16 byte header
    Integer x; // 4 + 24 bytes.
    Integer y; // 4 + 24 bytes.
    Boolean b; // 1 byte
    // 7 bytes of padding.
}

class Row { // uses a total of 32 bytes in a 32-bit JVM
    // 16 byte header
    int x; // 4  bytes.
    int y; // 4 bytes.
    boolean b; // 1 byte
    // 7 bytes of padding.
}

class Rows { // uses a total of 8-9 bytes/row
    // 16 byte header
    int[] x; // 4 bytes/row, TIntArrayList is easier to use.
    int[] y; // 4 bytes/row
    BitSet b; // 1 bit/row
    // 7 bytes of padding.
}

// if your numbers are between -32,768 and 32,767
class Rows { // uses a total of 4-5 bytes/row
    // 16 byte header
    short[] x; // 4 bytes/row, TShortArrayList is easier to use.
    short[] y; // 4 bytes/row
    BitSet b; // 1 bit/row
    // 7 bytes of padding.
}

答案 1 :(得分:0)

一些想法 -

1)如果文件是1GB,您可以将其加载到数据结构中,但您可能已经尝试过这个 2)如果按行对数据进行排序或分组,则可以读取每一行,直到找到新行并重新平衡 3)如果数据未排序,您可以使用随机访问IO类对文件进行就地排序,然后执行2) 4)如果那是不可能的,你总是可以对文件中的每一行进行多次传递,这显然会很慢。

答案 2 :(得分:0)

如果您使用轻量级数据库 - 德比,h2等会发生什么?我想你可以编写排序,过滤等查询来达到你想要的......