Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 读取文件两次在第二次读取时速度非常快_Java_Caching_Inputstream_File Read - Fatal编程技术网

Java 读取文件两次在第二次读取时速度非常快

Java 读取文件两次在第二次读取时速度非常快,java,caching,inputstream,file-read,Java,Caching,Inputstream,File Read,我现在正在写一个小程序来经常测试我的网速。 为了测试计算开销,我将读取源更改为磁盘上的文件。在这里,我注意到字节读取将速度限制在31 MB/s左右,因此我将其改为读取512 KB的块 现在我有一个非常奇怪的行为:在第一次读取1GB文件后,接下来的每个读取操作都在不到一秒钟的时间内完成。但我的普通硬盘读取速度不可能超过1 GB/s,我也无法想象整个文件都缓存在RAM中 这是我的密码: import java.io.File; import java.io.FileInputStream; impo

我现在正在写一个小程序来经常测试我的网速。 为了测试计算开销,我将读取源更改为磁盘上的文件。在这里,我注意到字节读取将速度限制在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
如果我将文件源更改为internet上的某个文件或SSD上更大的文件,我不会有这种行为


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

您可以看到缓存启动的效果。第一次读取文件后,大部分文件仍缓存在FS内存中。不是一个有效的基准…而且我也不能想象整个文件都缓存在RAM中。为什么不呢?@T.J.Crowder我不知道。因为它是一个完整的GB:D,但显然是。缓存发生在哪里?Windows正在这样做吗?磁盘本身包含缓存,比通过正常方式访问快得多。它们缓存频繁或最近访问的数据。我稍后会找出一些链接,否则有人可能会在那之前提供更详细的答案。是的。你的硬盘可能也有一个内置的高速缓存,但相比之下,它会是64MB之类的东西。