写入文件所花费的时间减少以用于后续程序运行

时间:2015-09-09 09:19:19

标签: java caching io

我在Eclipse中编写了一个java程序,它将3000万行写入文件。 第一次运行此代码时,写入文本文件(foo.txt)所花费的时间大约需要104秒。
我删除了我写过行的文本文件(foo.txt),然后再次运行程序。这次需要61秒。

我继续这个过程,每次运行程序时写入文件所花费的时间都在减少。写入文件的记录时间如下:

(以秒为单位,近似值)
104-> 61-> 39-> 25-> 18-> 16-> 16-> 16-> ...

我观察到的是,写入文本文件(foo.txt)所花费的时间一直在减少,直到它在16秒左右变得恒定。

我的java代码如下:

import java.io.File;  
import java.io.FileWriter;  
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

public class fileWrite {  
private static int file_sz = 30000000;  
private static final String line = "Help I am a chinese guy trapped in a fortune cookie factory!!";
 /*
No offense meant to any Chinese person, i apologise in advance if i have hurt your feelings.
*/ 

private static void write(List<String> list, Writer writer)throws IOException {
    long start  = System.currentTimeMillis();
    for(String list_el: list){
        writer.write(list_el);
    }
    writer.flush();
    writer.close();
    long end = System.currentTimeMillis();
    System.out.println((end-start)/1000f + "seconds");

}
public static void main(String[] args) {
    try{
        File file = new File("foo.txt");
        if(!file.exists()){
            file.createNewFile();
        }
        FileWriter writer = new FileWriter(file.getAbsolutePath());
        List<String> records = new ArrayList<String>(file_sz);
        for(int i = 0;i<file_sz;++i){
            records.add(line);
        }
        write(records,writer);
    }
    catch(Exception ex){
        ex.printStackTrace();
    }
}

}

我想问的问题是:

为什么写入文件所需的时间变得不变? 时间减少是否与缓存有关?

如果有人能够了解幕后发生的事情,我将非常感激。任何能够详细解释系统工作的链接也会受到欢迎。

提前谢谢。

1 个答案:

答案 0 :(得分:2)

这可能是您的操作系统,特别是您的文件系统正在完成其工作。

文件系统将文件表示为一系列块或范围;这样,文件就不必一直适合您的存储介质。

第一次编写文件时,文件系统以它可以找到的第一个空闲块开始,写入时,获得下一个空闲文件,将其添加到文件中的块列表中,依此类推

随着文件的增长,文件系统放弃了在其他块之间查找块,但在介质上获得了连续的可用空间块,并且始终将下一个块附加到文件中。这既降低了文件系统开销,又降低了硬盘驱动器的开销,减少了由于写标头缓慢进入新位置而导致的延迟。

现在,删除原始文件后,文件系统内部指针指向&#34;第一个空闲块&#34;可能仍然在连续的自由空间区域。

此外,现代操作系统可能很聪明,并且了解您的程序始终在特定文件夹中打开一个文件以进行访问,并在其中放入大量数据,因此可能会优化文件系统的工作方式。

最可能发生的事情是Java和你的操作系统都在RAM中有写缓存,它存储在实际写入磁盘之前/之前写入文件的数据。这些缓存是有弹性的;当您编写大量数据时,操作系统会占用更多空闲RAM用于写入缓存(例如,远离读取缓存)。程序完成后,不再需要写入缓存 - 但由于它没有以任何其他方式使用,下次编写大文件时,操作系统可以非常快速地将该内存分配给写入缓存