2017-05-08 127 views
2

我有一个包含数千行的文本文件。如何找到文件中是否存在某个字符串?查找文件中是否存在字符串的最佳方法

要么通过读取整个文件转换成字符串&然后使用string.contains方法或由该行是否包含所需的字符串或不使用创建所有行的列表Files.readAllLines方法&然后通过各行从列表中循环&检查?

更新:我使用Java 7.搜索限于每个文件1-2个字符串搜索(10个文件)。要搜索的字符串随文件而变化。如果找到字符串,我想停止搜索。

+1

查找字符串搜索算法一样[拉宾 - 卡普(https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm)和[阿霍 - Cosarick(https://开头恩.wikipedia.org/wiki/Aho%E2%80%93Corasick_algorithm) – Oswald

+0

不知道这种情况发生的频率很难回答你的问题。即它是一次性搜索?是经常发生的搜索,而是经常用于查找变化的输入字符串?是经常发生的搜索,但输入文件经常变化? – Catchwa

+0

你的要求究竟是什么?在任何一行中都找到了字符串,你想停止吗?或者你想打印所有的事件? –

回答

5

由于文件包含很多行,因此逐行读取该文件将更好,而不是将所有内容都读入程序存储器。所以基本上,读一行检查你的字符串的存在和向前移动。

3

考虑到您使用Java 8的情况,并且文件体积庞大,最好使用Streams API。可能有两种情况:一种是您找到包含您想要返回的stringToSearch的行的时刻,或者您想要查找所有寻找stringToSearch的行。示例代码将是这样的:

String fileName = "c://SomeFile.txt"; 
String stringToSearch = "dummy"; 
try (Stream<String> stream = Files.lines(Paths.get(fileName))) { 
    // Find first 
    Optional<String> lineHavingTarget = stream.filter(l -> l.contains(stringToSearch)).findFirst(); 
    // search all 
    stream.filter(l -> l.contains(stringToSearch)).forEach(System.out::println); 
    // do whatever 
    } catch (IOException e) { 
     // log exception 
    } 

所以读取文件的所有行似乎是一个坏主意。它更好地逐行阅读。如果您有兴趣了解最快的字符串搜索alogrithm,请检查this链接。

0

保持列表中的行几乎没有好处。不过,你提出的两种方法都有同样的警告。

如果您只关心文件中的特定行,则可能不希望在内存中保留不需要的行。如果您使用的是Java 8,则可以使用Files.lines()通过流逐行读取文件。否则,番石榴的LineProcessor,也可以做到这一点。

本示例使用流来查找与字符串匹配的所有行,并将它们返回到列表中。

List<String> lines = Files.lines(path) 
      // findFirst() can be used get get the first match and stop. 
      .filter(line -> line.contains("foo")) 
      .collect(Collectors.toList()); 

这是一个使用番石榴。

import com.google.common.io.Files; 
import com.google.common.io.LineProcessor; 

List<String> lines = Files.readLines(file, new LineProcessor<List<String>>() { 

    private List<String> lines = new ArrayList<>(); 

    @Override 
    public boolean processLine(String line) throws IOException { 
     if (line.contains("foo")) 
      lines.add(line); 
     return true; // return false to stop 
    } 

    @Override 
    public List<String> getResult() { 
     return lines; 
    } 

}); 
相关问题