Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 解析大型文件的问题_Java_Parsing - Fatal编程技术网

Java 解析大型文件的问题

Java 解析大型文件的问题,java,parsing,Java,Parsing,我正在解析文档并写入磁盘对,例如: 0 vs 1, true 0 vs 2, false 0 vs 3, true 1 vs 2, true 1 vs 3, false .. 0对1,对 0对2,错误 0对3,对 1对2,对 1对3,错 .. 等等 依次地,我通过删除随机行(如果超过,则带有true值的行,反之亦然)来平衡每个实例的true和False行,最后我得到一个文件,例如: 0 vs 1 true 0 vs 2 false 1 vs 2 true 1 vs 3 true 1 vs 4 f

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

0 vs 1, true 0 vs 2, false 0 vs 3, true 1 vs 2, true 1 vs 3, false .. 0对1,对 0对2,错误 0对3,对 1对2,对 1对3,错 .. 等等

依次地,我通过删除随机行(如果超过,则带有true值的行,反之亦然)来平衡每个实例的true和False行,最后我得到一个文件,例如:

0 vs 1 true 0 vs 2 false 1 vs 2 true 1 vs 3 true 1 vs 4 false 1 vs 5 false 0对1正确 0对2错误 1对2正确 1对3正确 1对4错 1对5错 false通常比True多得多,因此在前面的示例中,我只能为isntance 0保留1个false,而为实例1保留2个false

在解析和平衡之前,我分两步完成这个过程

现在,我的问题是这个不平衡的文件太大了:超过1GB,并且它的大部分行将通过平衡步骤被删除

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

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

我希望这是清楚的。
谢谢

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

我建议您读取数据,直到实例号更改(或达到文件末尾)为止,该更改应远小于1GB,并在内存中修复

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

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

另一个选择是尝试以不同的方式将整个文件加载到内存中。您应该能够以这种格式加载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) 如果文件为1GB,您可能可以将其加载到数据结构中,但您可能已经尝试过这种方法 2) 如果数据按行排序或分组,则可以读取每一行,直到找到新行并重新平衡 3) 如果数据未排序,您可以使用随机访问IO类对文件进行就地排序,然后执行2)
4) 如果这是不可能的,您可以对每一行的文件进行多次传递,这显然会很慢。

如果使用轻量级数据库(derby、h2等),会发生什么?我想您可以编写排序、筛选等查询,以得到您想要的结果…

那么,您正在读取一个大文件,然后在平衡的同时,您正在编写另一个大文件,然后再次读取它?我说的对吗?@pajton是的,我正在解析第一个文件,并用所有行构建第二个文件(实际上我不仅在解析,还平均了一些项..等等)。我依次从第二个文件中删除行并写入第三个。@Peter Lawrey是的,如果数据是随机排列的,另一个选项是计算每个实例的真和假的数量。但我担心这是一个糟糕的解决方案,我应该扫描每个实例组的所有文件,我有许多小组。我认为我应该改为使用数据库,Java和文本文件太慢了。。你认为呢?你应该能够在10-20秒内读/写1GB。我不相信你能更快地从数据库中加载1GB的数据。“另一个选择是计算每个实例的正确和错误数”如果我认为这是一个错误的选择,我不会建议这样做。另外,依次地,最好的做法可能是按组对行进行排序,这样它们就不再是随机排列的,我可以动态地平衡它们。嗯,你可能是对的:数据库比使用java和文本文件要快得多,对吧?有些数据库当然是,但我提到的那些数据库会编写常规的旧文件。区别在于他们如何写记录。数据库抽象还允许您扩展应用程序,而无需彻底检修专门的多阶段文件处理算法。本质上,我建议您将持久性、缓存和查询优化留给数据库开发人员,并专注于您正在解决的实际问题。通过正确的隔离级别调整等,您可以减少与数据库相关的开销,但可以获得它们的所有优点。我想这将大大提高性能。其次,我确实需要按组对其进行排序,这可能与mysql查询有关,而不是与java编程有关。就像你说的那样,我可以在飞行中保持平衡。