想象一下,我有一个非常大的文本文件。 表现真的很重要。
我想要做的就是扫描它以寻找某个字符串。 也许我想算一下我有多少,但这真的不是重点。
重点是:最快的方法是什么?
我不关心它需要快速的维护。
快速是关键。
答案 0 :(得分:16)
对于一次性搜索,请按照建议Scanner
使用here一种很简单的技术 比indexOf()快得多 使用扫描仪,使用该方法 findWithinHorizon()。如果你使用 获取File对象的构造函数, 扫描仪将内部制作一个 FileChannel读取文件。并为 模式匹配将最终使用 一种有效的Boyer-Moore算法 字符串搜索。
答案 1 :(得分:4)
首先,使用nio(FileChannel
)而不是java.io
类。其次,使用像Boyer-Moore这样的高效string search algorithm。
如果您需要针对不同的字符串多次搜索同一文件,您需要构建某种索引,请查看Lucene。
答案 2 :(得分:1)
将整个文件加载到内存中,然后使用字符串搜索算法,例如Knuth Morris Pratt。
编辑:
一个快速谷歌显示this字符串搜索库,似乎已实现了一些不同的字符串搜索算法。注意我从来没有使用它所以不能保证它。
答案 3 :(得分:0)
无论具体是什么,内存映射IO通常都是答案。
编辑:根据您的要求,您可以尝试将文件导入SQL数据库,然后通过JDBC利用性能改进。
Edit2:JavaRanch上的this thread还有一些其他想法,涉及FileChannel。我想这可能正是你在寻找的东西。
答案 4 :(得分:0)
我认为你可以获得的最快速度是在FileInputStreams之上使用BufferedInputStreams ...或者如果你想避免BufferedInputStream实例化,可以使用自定义缓冲区。
这将比我更好地解释:http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/
答案 5 :(得分:0)
使用正确的工具:全文搜索库
我的建议是在内存索引(或启用了缓存的基于文件的索引)中执行,然后对其执行搜索。正如 @Michael Borgwardt 所说,Lucene是最好的图书馆。
答案 6 :(得分:0)
我不知道这是不是一个愚蠢的建议,但不是一个非常有效的文件搜索工具吗?也许你可以使用Runtime.getRuntime().exec(..)
答案 7 :(得分:0)
这取决于您是否需要为每个文件执行多次搜索。如果只需要进行一次搜索,请从磁盘中读取文件并使用Michael Bogwart建议的工具进行解析。如果您需要进行多次搜索,则应该使用Lucene之类的工具构建文件索引:读取文件,标记它,在索引中粘贴标记。如果索引足够小,请将其放在RAM中(Lucene提供RAM选项或磁盘支持索引)。如果不保留在磁盘上。如果它对于RAM太大而且你非常非常非常关心速度,那么将索引存储在固态/闪存驱动器上。