如何将文件加载到主存中?
我使用阅读文件,我使用
BufferReader buf = new BufferedReader(FileReader());
我认为这是从磁盘逐行读取文件。这样做有什么好处?
将文件直接加载到内存有什么好处?我们如何在 Java 中做到这一点?
我发现了一些关于Scanner
或RandomAccessFile
方法的例子。他们是否将文件加载到内存中?我应该使用它们吗?我应该使用这两者中的哪一个?
提前致谢!!!
BufferReader buf = new BufferedReader(FileReader());
我认为这是从磁盘逐行读取文件。这样做有什么好处?
不完全是。它以块的形式读取文件,其大小是默认缓冲区大小(我认为是 8k 字节)。
优点是你不需要一个巨大的堆来读取一个巨大的文件。这是一个重要的问题,因为最大堆大小只能在 JVM 启动时指定(使用 Hotspot Java)。
您也不会消耗系统的物理/虚拟内存资源来表示巨大的堆。
将文件直接加载到内存有什么好处?
它减少了系统调用的数量,并且可以更快地读取文件。快多少取决于许多因素。而且你有处理非常大的文件的问题。
我们如何在 Java 中做到这一点?
read(byte[], int, int)
或read(char[], int, int)
方法读取整个文件。您也可以使用内存映射文件……但这需要使用Buffer
API,使用起来可能有点棘手。
我发现了一些有关 Scanner 或 RandomAccessFile 方法的示例。他们是否将文件加载到内存中?
不,也不。
我应该使用它们吗?我应该使用这两者中的哪一个?
它们是否提供了您需要的功能?您需要读取/解析基于文本的数据吗?您需要对二进制数据进行随机访问吗?
在正常情况下,您应该主要根据您需要的功能,其次是性能考虑来选择您的 I/O API。如果您打算在阅读时对其进行解析,则使用BufferedInputStream
orBufferedReader
通常足以获得可接受的*性能。(但如果您确实需要将整个文件以其原始形式保存在内存中,那么BufferedXxx
包装类实际上会使读取速度变慢。)
* - 请注意,可接受的性能与最佳性能不同,但您的客户/项目经理可能不希望您浪费时间编写代码以实现最佳性能......如果这不是规定的要求。
如果您正在读取文件然后对其进行解析,从头到尾一次提取数据,然后不再引用该文件,那么缓冲读取器与您将获得的“最佳”差不多。您可以通过调整缓冲区大小来“调整”性能——更大的缓冲区将从文件中读取更大的块。(将缓冲区设为 2 的幂 - 例如 262144。)读取整个大文件(例如,大于 1mb)通常会降低分页和堆管理的性能。