我试图使用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倍以上。远不止这些。那么,这是为什么呢?有没有可能使这段代码更高效(不使用任何外部库)?
是因为磁盘访问的成本。让我们假设您将有一个大小为8kb的文件。8*1024次访问磁盘将需要读取该文件,而无需BufferedInputStream。
此时,BufferedStream进入场景并充当FileInputStream和要读取的文件之间的中间人。
在一个快照中,将获取字节块,默认值为8kb到内存,然后FileInputStream将从这个中间人读取字节。这将缩短操作时间。
private void exercise1WithBufferedStream() {
long start= System.currentTimeMillis();
try (FileInputStream myFile = new FileInputStream("anyFile.txt")) {
BufferedInputStream bufferedInputStream = new BufferedInputStream(myFile);
boolean eof = false;
while (!eof) {
int inByteValue = bufferedInputStream.read();
if (inByteValue == -1) eof = true;
}
} catch (IOException e) {
System.out.println("Could not read the stream...");
e.printStackTrace();
}
System.out.println("time passed with buffered:" + (System.currentTimeMillis()-start));
}
private void exercise1() {
long start= System.currentTimeMillis();
try (FileInputStream myFile = new FileInputStream("anyFile.txt")) {
boolean eof = false;
while (!eof) {
int inByteValue = myFile.read();
if (inByteValue == -1) eof = true;
}
} catch (IOException e) {
System.out.println("Could not read the stream...");
e.printStackTrace();
}
System.out.println("time passed without buffered:" + (System.currentTimeMillis()-start));
}
围绕FileInputStream的BufferedInputStream将以大块形式(我认为默认情况下是512字节左右)从FileInputStream请求数据因此,如果一次读取1000个字符,FileInputStream只需进入磁盘两次。这会快得多!
在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;
这是对使用磁盘读取单个字节的操作系统的本机调用。这是一项繁重的行动。
使用BufferedInputStream
,该方法委托给重载的read()
方法,该方法读取8192
字节数并缓冲它们,直到需要它们。它仍然只返回单个字节(但保留其他字节)。这样,BufferedInputStream对操作系统从文件中读取的本地调用就少了。
例如,您的文件是32768
字节长。要使用FileInputStream
获取内存中的所有字节,需要对操作系统进行32768
本机调用。使用BufferedInputStream
,您将只需要4
,而不管您将执行的read()
调用的数量(仍然是32768
)。
至于如何使它更快,您可能需要考虑java 7的NiO
注意:如果直接使用FileInputStream
的read(byte[], int, int)
方法,则使用byte[
问题内容: 我试图使用FileInputStream将文件读入数组,而一个〜800KB的文件花了大约3秒钟才能读入内存。然后,我尝试了相同的代码,只是将FileInputStream包装到BufferedInputStream中,这花费了大约76毫秒。为什么即使我仍在逐字节读取文件,使用BufferedInputStream逐字节读取文件的速度还是这么快?这是代码(其余代码完全无关)。请注意,这是
bufferedinputstream(BIS)比FileInputStream(FIS)快的原因请参见“为什么使用bufferedinputstream逐字节读取文件比使用FileInputStream快?”?是吗 使用BufferedInputStream,该方法委托给重载read()方法,该方法读取8192个字节,并在FIS读取单个字节时缓冲它们,直到需要它们 据我所知,磁盘是一个“块设备”
问题内容: 我有一个要在Java中读取的2 gb文件(实际上是四个2gb文件)。因此,Java 7中有一个新功能,可以让我一次读取所有字节。 这是一个愚蠢的程序,它将读取文件中预先输入一个字节的文件,然后连续读取该文件,并将读取的内容附加到同一文件中。现在显然,RAM不够大,无法一次读取2gb文件,更不用说其中的四个了,所以我想知道是否有任何快速方法,而无需使用外部库(除非这是唯一方法)来读取四个
问题内容: 如何使用fseek逐行读取文件? 代码可能会有所帮助。必须是跨平台和纯PHP。 提前谢谢了 问题答案: 问题是使用fseek进行询问,因此只能假定性能是一个问题,而file()不是解决方案。这是使用fseek的一种简单方法: 我的file.txt 和代码: 输出: 您不必像我一样附加到$ lines数组,如果这是脚本的目的,则可以立即打印输出。如果要限制行数,也很容易引入计数器。
本文向大家介绍Java使用FileInputStream / FileOutputStream读/写文件,包括了Java使用FileInputStream / FileOutputStream读/写文件的使用技巧和注意事项,需要的朋友参考一下 示例 写入文件test.txt: 从文件test.txt中读取: 请注意,自Java 1.7起引入了try-with-resources语句,这使得读/写操
问题内容: 我在S3中有一个csv文件,我正在尝试读取标题行以获取大小(这些文件是由我们的用户创建的,因此它们几乎可以是任何大小)。有没有办法使用boto做到这一点?我以为也许我们可以使用python BufferedReader,但是我不知道如何从S3键打开流。任何建议都很好。谢谢! 问题答案: 看来boto具有可以执行此操作的功能。这是一些对我有用的代码: 调用会从对象返回下一个n个字节。 当