在第二次读取时,两次读取文件非常快

时间:2015-02-09 09:30:05

标签: java caching inputstream file-read

我正在编写一个小程序,经常测试我的网速。 为了测试计算开销,我将读取源更改为磁盘上的文件。在这里,我注意到,逐字节读取将速度限制在大约31 MB / s,因此我将其更改为读取512 KB块。

现在我有一个非常奇怪的行为:第一次读取1GB文件后,每次后续读取操作都在不到一秒的时间内完成。但我的普通硬盘驱动器无法以超过1 GB / s的速度读取数据,而且我也无法将整个文件缓存在RAM中。

这是我的代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Main {

    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm");

        try {
            System.out.println("Starting test...");

            InputStream in = (new FileInputStream(new File("path/to/testfile")));

            long startTime = System.currentTimeMillis();
            long initTime = startTime + 8 * 1000; // start measuring after 8 seconds
            long stopTime = initTime + 15 * 1000; // stop after 15 seconds testing

            boolean initiated = false;
            boolean stopped = false;

            long bytesAfterInit = 0;

            long bytes = 0;

            byte[] b = new byte[524288];

            int bytesRead = 0;

            while((bytesRead = in.read(b)) > 0) {
                bytes += bytesRead;

                if(!initiated && System.currentTimeMillis() > initTime) {
                    initiated = true;
                    System.out.println("initiated");
                    bytesAfterInit = bytes;
                }

                if(System.currentTimeMillis() > stopTime) {
                    stopped = true;
                    System.out.println("stopped");
                    break;
                }
            }

            long endTime = System.currentTimeMillis();

            in.close();

            long duration = 0;
            long testBytes = 0;

            if(initiated && stopped) { //if initiated and stopped calculate for the test time
                duration = endTime - initTime;
                testBytes = bytes - bytesAfterInit;
            } else { //otherwise calculate the whole process
                duration = endTime - startTime;
                testBytes = bytes;
            }

            if(duration == 0) //prevent dividing by zero
                duration = 1;

            String result = sdf.format(new Date()) + "\t" + (testBytes / 1024 / 1024) / (duration / 1000d) + " MB/s";

            System.out.println(duration + " ms");
            System.out.println(testBytes + " bytes");
            System.out.println(result);


        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

输出:

Starting test...
302 ms
1010827264 bytes
09.02.2015 10:20    3192.0529801324506 MB/s

如果我将文件的来源更改为互联网中的某个文件或者我的SSD上更大的文件,我就没有这种行为。

如何在如此短的时间内读取所有字节?

0 个答案:

没有答案