我试图使用 FileInputStream 将一个文件读入一个数组,一个约 800KB 的文件需要大约 3 秒才能读入内存。然后我尝试了相同的代码,除了将 FileInputStream 包装到 BufferedInputStream 中,它花费了大约 76 毫秒。为什么使用 BufferedInputStream 逐字节读取文件的速度要快得多,即使我仍在逐字节读取它?这是代码(其余代码完全不相关)。请注意,这是“快速”代码。如果你想要“慢”代码,你可以删除 BufferedInputStream:
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(file));
int[] fileArr = new int[(int) file.length()];
for (int i = 0, temp = 0; (temp = is.read()) != -1; i++) {
fileArr[i] = temp;
}
BufferedInputStream 快 30 倍以上。远不止于此。那么,这是为什么呢,是否有可能让这段代码更高效(不使用任何外部库)?
最佳答案
在FileInputStream
中,方法read()
读取单个字节。来自源代码:
/**
* Reads a byte of data from this input stream. This method blocks
* if no input is yet available.
*
* @return the next byte of data, or <code>-1</code> if the end of the
* file is reached.
* @exception IOException if an I/O error occurs.
*/
public native int read() throws IOException;
这是对使用磁盘读取单个字节的操作系统的 native 调用。这是一项繁重的操作。
使用 BufferedInputStream
,该方法委托(delegate)给重载的 read()
方法,该方法读取 8192
数量的字节并缓冲它们,直到它们需要。它仍然只返回单个字节(但保留其他字节)。这样,BufferedInputStream
对操作系统的 native 调用减少以从文件中读取。
例如,您的文件是 32768
字节长。要使用 FileInputStream
获取内存中的所有字节,您需要对操作系统进行 32768
native 调用。使用 BufferedInputStream
,您将只需要 4
,无论您将执行多少次 read()
调用(仍然是 32768
)。
至于如何让它更快,你可能想考虑 Java 7 的 NIO FileChannel
类,但我没有证据支持这一点。
注意:如果您直接使用 FileInputStream
的 read(byte[], int, int)
方法,则使用 byte[>8192]
你不需要 BufferedInputStream
包装它。
关于java - 为什么使用 BufferedInputStream 逐字节读取文件比使用 FileInputStream 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18600331/