5

如何将文件加载到主存中?

我使用阅读文件,我使用

BufferReader buf = new BufferedReader(FileReader());

我认为这是从磁盘逐行读取文件。这样做有什么好处?

将文件直接加载到内存有什么好处?我们如何在 Java 中做到这一点?

我发现了一些关于ScannerRandomAccessFile方法的例子。他们是否将文件加载到内存中?我应该使用它们吗?我应该使用这两者中的哪一个?

提前致谢!!!

4

2 回答 2

7
BufferReader buf = new BufferedReader(FileReader());

我认为这是从磁盘逐行读取文件。这样做有什么好处?

不完全是。它以块的形式读取文件,其大小是默认缓冲区大小(我认为是 8k 字节)。

优点是你不需要一个巨大的堆来读取一个巨大的文件。这是一个重要的问题,因为最大堆大小只能在 JVM 启动时指定(使用 Hotspot Java)。

您也不会消耗系统的物理/虚拟内存资源来表示巨大的堆。

将文件直接加载到内存有什么好处?

它减少了系统调用的数量,并且可以更快地读取文件。快多少取决于许多因素。而且你有处理非常大的文件的问题。

我们如何在 Java 中做到这一点?

  1. 找出文件有多大。
  2. 分配一个足够大的字节(或字符)数组。
  3. 使用相关read(byte[], int, int)read(char[], int, int)方法读取整个文件。

您也可以使用内存映射文件……但这需要使用BufferAPI,使用起来可能有点棘手。

我发现了一些有关 Scanner 或 RandomAccessFile 方法的示例。他们是否将文件加载到内存中?

不,也不。

我应该使用它们吗?我应该使用这两者中的哪一个?

它们是否提供了您需要的功能?您需要读取/解析基于文本的数据吗?您需要对二进制数据进行随机访问吗?

在正常情况下,您应该主要根据您需要的功能,其次是性能考虑来选择您的 I/O API。如果您打算在阅读时对其进行解析,则使用BufferedInputStreamorBufferedReader通常足以获得可接受的*性能。(但如果您确实需要将整个文件以其原始形式保存在内存中,那么BufferedXxx包装类实际上会使读取速度变慢。)


* - 请注意,可接受的性能与最佳性能不同,但您的客户/项目经理可能不希望您浪费时间编写代码以实现最佳性能......如果这不是规定的要求。

于 2012-10-27T03:54:10.913 回答
4

如果您正在读取文件然后对其进行解析,从头到尾一次提取数据,然后不再引用该文件,那么缓冲读取器与您将获得的“最佳”差不多。您可以通过调整缓冲区大小来“调整”性能——更大的缓冲区将从文件中读取更大的块。(将缓冲区设为 2 的幂 - 例如 262144。)读取整个大文件(例如,大于 1mb)通常会降低分页和堆管理的性能。

于 2012-10-27T13:16:56.840 回答