您好,我编写了一个读取文件所有行的函数,我需要从此日志文件中搜索一行。该日志文件在开始时即添加时间戳。
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
,如何获取真值?我想获取日期旁边的所有字符串。有什么办法吗?还是有更好的方法来检查文件是否包含我们要查找的行。
答案 0 :(得分:3)
您的方法在内存上的效率很低,尤其是如果您的日志文件可能变得很大。 像这样简单的东西呢?
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;
。
这样,如果您要搜索的行是第一行,则您将不处理文件的其余部分。