Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.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_File_Java Io - Fatal编程技术网

在JAVA中多次处理大型文件

在JAVA中多次处理大型文件,java,file,java-io,Java,File,Java Io,我有一个文件a,其中包含一些大约40兆的记录。我有另一个文件B,其中包含了大约7000万条记录。现在,我必须迭代文件A,对于每个记录搜索,如果文件B中有条目,那么将条目写入文件C 请就如何在不影响记忆和最短时间的情况下实现这一目标提出建议。我已经尝试过ApacheLucene,但是它在创建索引方面有额外的开销,因为具有7000万条记录的文件B每天都会更改(即,我们从外部系统获取此文件)。每天重新创建索引是非常过分的将数据作为表拉入mysql或postgres。索引感兴趣的字段并进行连接。您可以使

我有一个文件a,其中包含一些大约40兆的记录。我有另一个文件B,其中包含了大约7000万条记录。现在,我必须迭代文件A,对于每个记录搜索,如果文件B中有条目,那么将条目写入文件C


请就如何在不影响记忆和最短时间的情况下实现这一目标提出建议。我已经尝试过ApacheLucene,但是它在创建索引方面有额外的开销,因为具有7000万条记录的文件B每天都会更改(即,我们从外部系统获取此文件)。每天重新创建索引是非常过分的

将数据作为表拉入mysql或postgres。索引感兴趣的字段并进行连接。

您可以使用历史地图

根据记录的大小,您应该能够在几秒钟到几分钟内加载7000万条记录。如果需要,您可以实时更新记录

由于编年史映射是持久化和非堆化的,您可以离线或在另一个过程中执行此操作(如果这有帮助的话)


或者你可以使用数据库,批量加载这样一个表不会超过几分钟。

假设你没有足够的内存来加载数据,也没有一个方便的数据库用于索引,那么最好使用数据库


本质上,按照连接/查找条件对两个文件进行排序,然后并行读取文件(“合并”)。

如果数据库不是一个选项,我有一个想法:

预处理第二个文件:抓取并按字母顺序排序:

现在创建一个文件,将每个字母表字符映射到行号,行号用作名称的起始字符:

A,0
C,2
J,3
V,5
前面的步骤称为预处理,您应该在编译程序之前执行这些步骤。显然,对如此庞大的文件进行排序将花费大量时间,但如果使用此方法,部署的程序将更快:

当您迭代第一个文件时,假设您找到了
Joseph
。您要做的是抓取第一个字符
J
,然后使用映射确定该字符使用的第一行号。映射将产生
3
,因此您将迭代第二个文件到这样的行号。这节省了大量时间,因为您可以在明显不符合搜索条件的几行上跳过使用
equals()
。要查找
Joseph
,您只需检查
Jeremy
,然后检查
Joseph

现在您已经了解了这项技术,您可以通过使用两个级别来提高效率:对于字母表中的每个字符,为字母表中的每个字符创建另一个映射。在
J
的情况下

JE,3
JO,4
由于您正在查找约瑟夫,因此很容易确定开始查找它的行号是第四个行号,从而跳过更多的比较

你可以在更多的层次上做到这一点:三,四,等等。。。这取决于你决定哪一个在你的情况下是最好的。映射不会占用太多空间,它们会跳过不必要的条目,从而节省大量时间

明显的缺点是,预处理一个包含7000万条目的文件是非常详尽的,但这是您的最终用户不必经历的

这是一种方法

注意:您仍然需要迭代第二个文件的每一行,以达到所需的行号。关键是,您不需要执行任何类型的比较—您将看到这将节省大量的处理时间

JE,3
JO,4