Java 基于大文件中字符串的权重求和

Java 基于大文件中字符串的权重求和,java,algorithm,file-io,Java,Algorithm,File Io,我很确定这里可能已经进行了修改/类似的讨论,但我想提出我所面临的确切问题以及我这边可能的解决方案。然后我想听听你们的意见,什么是更好的方法,或者我如何认可我的逻辑 问题 我有一个包含行的大文件。每行的格式如下,。现在我要做的是把所有同名物体的重量相加。问题是 我不知道文件中存在某些名称的频率有多高。它可能只出现一次,也可能是几百万次 没有订 我正在使用文件流(特定于java,但这并不重要) 解决方案1:假设我有巨大的ram,我计划做的是逐行读取文件,并在哈希图中使用名称作为键。如果已经存在,则将

我很确定这里可能已经进行了修改/类似的讨论,但我想提出我所面临的确切问题以及我这边可能的解决方案。然后我想听听你们的意见,什么是更好的方法,或者我如何认可我的逻辑

问题 我有一个包含行的大文件。每行的格式如下,。现在我要做的是把所有同名物体的重量相加。问题是

  • 我不知道文件中存在某些名称的频率有多高。它可能只出现一次,也可能是几百万次
  • 没有订
  • 我正在使用文件流(特定于java,但这并不重要)
  • 解决方案1:假设我有巨大的ram,我计划做的是逐行读取文件,并在哈希图中使用名称作为
    键。如果已经存在,则将其汇总,否则添加。这将花费我
    m
    ram(m=文件中的行数),但总体处理速度会很快

    解决方案2:假设我没有巨大的ram,我将分批执行。读取哈希表中的前10000,求和并将其转储到文件中。对文件的其余部分执行以下操作。处理完文件后,我将开始读取处理过的文件,并将重复此过程以总结所有内容

    你们有什么建议吗


    除了你的建议之外,我可以并行读取文件吗?我可以在这里访问FileInputStream,我可以使用FileInputStream来提高文件读取效率吗

    执行此计算时,文件是静态的吗?如果是这样,那么您可以根据名称对文件进行磁盘排序,并将连续条目相加

    第二种方法对您没有帮助:为了生成最终输出,您需要足够的RAM来保存文件中的所有键,以及一个表示计数的
    整数。无论您是要在一个大步中实现它,还是一次迭代10K行,都不会改变最终需要的占用空间

    有帮助的是以某种方式对键进行分区,例如按键的第一个字符进行分区。如果名称以字母开头,则处理该文件26次,第一次只取从
    'a'
    开始的键的权重,忽略所有其他键,第二次只取
    'B'
    s,依此类推。这将使您得到26个不相交的文件

    另一种有效的方法是使用将无序文件转换为有序文件。这将允许您遍历已排序的文件,边走边计算总数,并将它们写入输出,即使不需要内存中的表


    就优化I/O而言,我建议使用
    java.nio.file.Files
    类的方法:它为您提供了一个
    BufferedReader
    ,它针对读取效率进行了优化。

    并行读取?大多数硬盘都会让速度变慢。。。很多阅读与处理并行,当然,这会起作用,也不会太难,但不会给速度带来太大的提升(阅读应该比处理慢得多)。“第二种方法对你没有帮助”。。。除非它们已排序,否则在这种情况下,您可以执行类似于合并排序的过程。将散列写入文件实际上应该以一个排序列表结束,尽管它是按散列、mod something排序的。@Dukeling OP表示条目没有排序(请参阅要点2)。仅仅因为原始文件没有排序,并不意味着不能对中间文件排序。@Dukeling对中间文件排序没有帮助,因为多个文件可能最终包含属于同一密钥的数据。是的,但您可以同时单步遍历多个文件,在运行时流式处理到另一个文件,从而只保留每个文件在内存中的位置。