首页 > 解决方案 > 如果文件包含搜索字符串如何获取它

问题描述

嗨我写了一个读取文件所有行的函数,我需要从这个日志文件中搜索一行。此日志文件在开头添加时间戳,即

2019/04/26 20:37:47 -- Searching this line

public static boolean containsLine(String line) {
        BufferedReader br = null;
        Reader reader = null;
        InputStream is = null;
        boolean isInstalled = false;
        List<String> fileOutput = new ArrayList<String>();

        try {
            String searchLine;
            is = new FileInputStream(logFile);
            reader = new InputStreamReader(is, "UTF-8");
            br = new BufferedReader(reader);

            while ((searchLine = br.readLine()) != null) {
                fileOutput.add(searchLine);
            }

            if (fileOutput.contains(line)) {
                isInstalled = true;
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (reader != null) {
                try {
                    reader.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return isInstalled;
    }

如果文件包含字符串,我怎样才能得到一个真实的Searching this line我想获取日期旁边的所有字符串。有没有办法做到这一点?或者有没有更好的方法来检查文件是否包含我们正在寻找的行。

标签: java

解决方案


您的方法在内存上效率很低,尤其是在您的日志文件可能变得很大的情况下。像这样简单的东西呢:

public static boolean containsLine(File logFile, String line) {
  try (Stream<String> stream = Files.lines(logFile.toPath())) {
    return stream.anyMatch(fullLine-> fullLine.contains(line));
  } catch (IOException e) {
    e.printStackTrace();
    return false;
  }
}

这会延迟加载文件,并在找到文件的那一刻String停止,而无需遍历所有其余行。

如果您有大文件,您甚至可以通过stream.parallel.anyMatch(...).

如果您使用的是不支持流的古老 JDK,如果您稍微修改一下代码,您仍然可以以相同的方式复制它。无需将文件的所有行加载到数组中,您只需将 while 循环替换为:

  while ((searchLine = br.readLine()) != null) {
    if (searchLine.contains(line)) {
       return true;
    }
  }

并删除数组和与之相关的任何代码,最后return false;. 这样,如果您要搜索的行是第一行,您就不会无缘无故地处理文件的其余部分。


推荐阅读