【发布时间】:2013-08-26 09:48:22
【问题描述】:
我想知道像 Bairtail 或 Baregrep 这样的应用程序如何处理如此大的文本文件而不占用大量空间?
我正在尝试在 Java 中做类似的事情:
Viewing large log files in JavaFX in a ListView
但是当我处理大型文本日志文件(900Mb 到 2.5Gb 的文本)时,我遇到了问题。当我阅读文本文件时,JVM 内存大小急剧增加。
另一种方法是只检索我感兴趣的行。但我不知道在 java 中有任何技术可以做到这一点。我必须开始逐行阅读,直到我到达我想要的所需行(比如说第 1000 行),然后抓住那个文本。但这样做时,我在内存中有 999 行等待被 GC 处理。
例如,Bairgrep 正在扫描文件夹中的多个文件并寻找模式。如果我打开任务管理器,我几乎看不到内存占用正在增长。这些程序使用什么类型的技术或扫描方式。
有没有可以在我的应用程序中使用的技术来处理大型文本文件?
我可能会补充一点,我的日志文件是由 java 应用程序生成的文件,并且每行的长度不一样。
一个更正...内存占用我的意思是我无法读取内存中的 6Gb 文件。如果我使用 -Xmx 将 VM 大小指定为较小的事件。读取 6Gb 文件时应用程序内存不足。
添加了两种我尝试从 758 Mb 日志文件中获取文本的方法
方法一
@FXML
private void handleButtonAction(ActionEvent event) {
final String fileName = "D:/Development/Logs/File1.log";
try {
BufferedReader in = new BufferedReader(new FileReader(fileName));
while (in.ready()) {
String s = in.readLine();
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
方法二
@FXML
private void handleButtonAction(ActionEvent event) {
final String fileName = "D:/Development/Logs/File1.log";
Scanner scan = null;
try {
File file = new File(fileName);
if (!file.exists()) {
return;
}
scan = new Scanner(file);
long start = System.nanoTime();
while (scan.hasNextLine()) {
final String line = scan.nextLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
scan.close();
}
}
【问题讨论】:
-
“等待 GC”的数据不会增加应用程序的内存占用。如果您想减少占用空间,请使用
-Xmx指定它。 -
@Marko-我更新了问题。我的意思是,如果我让虚拟机太小,它会在读取文件时耗尽内存。
-
如果您的内存不足,则说明您的代码存在问题。如果您不在内存中保留较早的行,则没有理由发生 OOME。
-
让我们看一些代码。没有理由 java 必须保留它从文件中读取的每一行。
-
添加了使用 BufferedReader 和扫描器类的代码。这两种情况每次调用该方法时内存都会跳跃大约 200mb。
标签: java parsing java-7 large-files