1

我正在用 Java 编程。我想定期计算特定文件夹中所有文件的大小。周期不是恒定的,而且很短。我的代码如下:

//get Index Size
index_byte_size = 0;
File index = new File(indexPath);
String[] files = index.list();
File f = null;
for(int i=0; i < files.length; i++) {
    f = new File(index, files[i]);
    index_byte_size += f.length();
}

index_byte_size是我想要得到的。indexPath是文件夹的路径。

代码在一个循环中。我index_byte_size在每个循环后输出总数。据我所知,文件大小应该不断增加。但是,我得到的结果是这样的:

IndexSize(byte) Time(ms)
0   297
0   802
0   1293
0   1710
7769547 2952
7769547 4330
7769547 4431
7769547 4785
7769547 4901
7769547 5213
7769547 5279
7769547 5446
7769547 5660
7769547 5861
7769547 6155
24041054    8763
24041054    9203
24041054    10439
24041054    10820
24041054    11685
36708630    13662
36708630    14309
36708630    16065
36708630    16192
36708630    16374
36708630    16691
36708630    16899
...

如您所见,文件大小只是增加,然后保持不变,然后增加......我不知道发生了什么,我猜操作系统发生了一些事情。我的操作系统是 Windows 7。


[背景]

我想用Lucene做一个实验,看看它的索引能力,特别是它的索引大小和索引效率。

我有很多小文本文件(每个 2-10M 大小)。而且我想看看Lucene需要多长时间才能对它们中的每一个进行索引,以及索引会有多大。所以我写了这个程序。

我不想在索引更改时收到通知(因为它们当然会更改)。我只是在很短的时间内知道它们有多长和多大。


有谁知道为什么?以及如何实时计算大小?

4

1 回答 1

2

应用程序通常会缓冲输出并仅批量推出数据。

我怀疑这里不是这种情况。相反,我怀疑 Lucene 正在使用内存映射文件。当您增长内存映射文件时,它会随着您所做的每次分配而增长。由于分配是昂贵的,但分配超过您需要的成本相当便宜(因为它使用虚拟内存并且仅在您触摸它时使用主内存和磁盘)最有效的做法是分配大块然后填充它们懒洋洋地起来。(例如,我使用 64 位 JVM 一次分配 128 MB)

File.length 为您提供文件的范围,而不是实际使用了多少或什至使用了多少磁盘空间。您可以看到在 unix 上使用了多少磁盘空间du,可能还有 Java 7 中的一些工具(我只找到了用于文件系统根目录的空间,而不是文件)

即便如此,这仍会告诉您已触摸了多少页。准确知道使用了多少的唯一方法是读取文件,如果在您阅读文件时正在修改文件,则准确性有限。

编辑:在 Windows 7 上,空间似乎立即被保留,因此您无法创建大于文件系统大小的稀疏文件(就像在 ext4 文件系统上一样)

于 2012-12-19T13:57:30.100 回答