RandomAccessFile.seek()方法是如何工作的?

11 浏览
0 Comments

RandomAccessFile.seek()方法是如何工作的?

根据API,以下是事实:\n

    \n

  • seek(long bytePosition)方法简单来说,将指针移动到指定的位置,该位置由bytePosition参数指定。
  • \n

  • bytePosition大于文件长度时,文件长度不会改变,除非在(新的)末尾写入一个字节。
  • \n

  • 如果跳过的长度中存在数据,则该数据保持不变。
  • \n

\n然而,我感兴趣的情况是:当文件没有数据(0字节)且执行以下代码时:\n

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

\n所有的100,000字节几乎瞬间都被填充为0。我可以在10毫秒内读取超过200GB。\n但是,当我尝试使用其他方法(如BufferedOutputStream)写入100,000字节时,同样的过程需要几乎无限长的时间。\n这个时间差的原因是什么?有没有更有效的方法来创建一个包含n字节并填充为0的文件?\n编辑:\n如果实际上并没有写入数据,那么文件是如何被填充的呢?\n看一下这段代码:\n

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

\n这是输出:\n\"Output\"\n另外,如果文件足够大,由于空间不足,我将无法继续向磁盘写入。

0
0 Comments

如何使用RandomAccessFile.seek()方法?

在操作系统和文件系统支持稀疏文件的情况下,seek方法会利用此功能实现。这与Java无关,它实际上是C库中fseek和fwrite函数的一种特性,这两个函数很可能是您所使用的JRE中File实现背后的后端。

如果操作系统支持,您可以使用truncate方法将文件截断为所需大小,而不是发出write调用。然而,这似乎在Java API中不可用。

稀疏文件必须是稀疏的。它必须通过seek操作创建。如果您向文件写入0或任何其他字节,则它就不是稀疏的。在文件中进行seek操作不会删除任何内容,它只是移动文件指针。

所以,如何实现seek方法呢?是否有一种方法可以查看内置库方法的实现呢?这适合作为另一个问题发布。

感谢您的答案。稀疏文件是否会覆盖已删除的数据呢?(数据已删除但尚未被覆盖)

以上就是关于RandomAccessFile.seek()方法的原因和解决方法的整理。

0
0 Comments

当您使用BufferedOutputStream写入100,000个字节时,您的程序会显式地访问文件的每个字节并写入零。

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

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

当您通过fseek()定位到第50,000个字节并进行读取时,操作系统可以说:“好的,我没有为第50,000个字节分配磁盘空间,因为我已经记录了字节0到100,000为空。因此,我可以返回0作为该字节的值。”这对调用者来说是不可见的。

这既节省了磁盘空间,又提高了速度。您已经注意到了速度的提升。

更一般地说,fseek()直接跳转到文件中的一个位置,因此它的时间复杂度是O(1),而不是O(n)。如果将文件与数组进行比较,这就像执行x = arr[n]而不是for(i = 0; i<=n; i++) { x = arr[i]; }

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

这个回答也解决了您的修改。数据都是0,这是由稀疏文件处理的。

感谢回答。

稀疏文件是否也会覆盖已删除的数据?(已删除但尚未覆盖的数据)

根据阅读此描述,我理解它不会,但是我进行了实验并发现我无法使用Piriform的Recuva恢复文件。(Windows 10)

如果您有其他问题,请将其作为一个新问题提问-但是您将需要解释您所指的“覆盖已删除的数据”和“已删除但尚未覆盖的数据”。此外,这可能属于不同的Stack Exchange站点,这取决于您询问的操作系统。

0