2017-02-23 22 views
1

作为每API,这些都是事实:RandomAccessFile.seek()如何工作?

  • seek(long bytePosition)方法简单地说,将指针移动到 与bytePosition参数指定的位置。
  • bytePosition大于文件长度时,文件 长度不会改变,除非在(新)结束处写入一个字节。
  • 如果数据以跳过的长度存在,则这些数据不会被触发,而是保留 。

不过,我很好奇的情况是:当有没有数据(0字节)的文件,我执行下面的代码:

file.seek(100000-1); 
file.write(0); 

所有100,000字节几乎立即填满0。比如说,我可以在10毫秒内超过200GB。

但是,当我尝试使用其他方法(例如BufferedOutputStream)写入100000字节时,同一个过程需要几乎无限长的时间。

这种时间差异的原因是什么?有没有更有效的方法来创建n字节的文件并填写0

编辑: 如果数据没有实际写入,那么文件如何填充数据? 样品验证码:

RandomAccessFile out=new RandomAccessFile("D:/out","rw"); 
out.seek(100000-1); 
out.write(0); 
out.close(); 

这是输出:

Output

另外,如果该文件是足够庞大的我不能再写入磁盘,由于缺乏空间。

+0

我的猜测是文件大小是“注意到”的,但实际的块没有写入磁盘。冲洗/关闭需要多长时间? (请参阅这里http://stackoverflow.com/a/257849/540873) –

+0

我的猜测是一样的,但我打开文件并检查它。当我没有写最后一个字节时,它是空的,结果文件大小为0字节。当我写完最后一个字节时,直到最后一个字节的每个字节都填充0,文件大小作为输入。包含close()操作的整个过程是问题中指定的时间(这就是为什么我很惊讶!) – SirVirgin

+0

当您阅读该方法的源代码时,您不明白什么?在请求别人阅读它之前,确实已经阅读了信息来源,你是否为你工作了吗? –

回答

3

当你写100,000字节到BufferedOutputStream,你的程序是明确的访问文件的每个字节,写一个零。

在本地文件上使用RandomAccessFile.seek()时,您间接使用C系统调用fseek()。如何处理取决于操作系统。

在大多数现代操作系统,sparse files支持。这意味着如果您要求一个空的100,000字节文件,实际上并未使用100,000个字节的磁盘空间。当您写入字节100,001时,操作系统仍然不使用100,001字节的磁盘。它为包含“真实”数据的块分配少量空间,并分别跟踪空闲空间。

当你阅读稀疏文件,例如,通过fseek() ING至字节50,000,然后看书,操作系统可以说“为字节50000 OK,我还没有分配的磁盘空间,因为我已经注意到,字节0〜 100,000是空的,因此我可以为这个字节返回0。“。这对调用者来说是不可见的。

这具有节省磁盘空间和提高速度的双重目的。你已经注意到速度的提高。

更一般地,fseek()直接进入在文件中的位置,所以它的O(1),而不是为O(n)。如果你将一个文件与一个数组进行比较,就像做x = arr[n]而不是for(i = 0; i<=n; i++) { x = arr[i]; }

这个描述和维基百科上的描述可能足以理解为什么寻找字节100,000然后写入比写入10万个零更快。但是,您可以阅读Linux内核源代码以查看稀疏文件的实现方式,您可以阅读JDK中的RandomAccessFile源代码以及JRE源代码,以了解它们如何交互。但是,这可能比您需要的更详细。

+0

为什么downvote?这是一个很好的答案。 – Gray

+0

我没有downvote。请参阅编辑 – SirVirgin

+0

此答案处理您的编辑以及@RangaRajan。数据是由稀疏文件处理的0。 – Gray

1

您的操作系统和文件系统支持稀疏文件时,它的的情况下,寻求实现利用这一功能。

这不是真的与Java有关,它只是C库中的fseekfwrite函数的一个特性,它很可能是您正在使用的JRE的文件实现背后的后端。

更多信息:https://en.wikipedia.org/wiki/Sparse_file

是否有创建的n个字节的文件,并以0填充它更有效的方法?

在支持它的操作系统上,您可以将truncate文件转换为所需的大小,而不是发出write调用。但是,这似乎在Java API中不可用。

+0

你会如此善良以详细说明吗?另外如何实现seek()方法?有没有一种方法可以看到内置的库方法是如何实现的? – SirVirgin

+0

为什么downvote?这是一个很好的答案。 – Gray

+0

我没有downvote。另外,请参阅编辑。 – SirVirgin