- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
根据 API ,这些是事实:
seek(long bytePosition)
方法简单来说就是将指针移动到用 bytePosition
指定的位置参数。bytePosition
大于文件长度,则文件除非在(新)末尾写入一个字节,否则长度不会改变。但是,我很好奇的情况是:当存在一个没有数据(0字节)的文件时,我执行以下代码:
file.seek(100000-1);
file.write(0);
这 100,000 字节全部填充为 0
几乎是瞬间。我可以在 10 毫秒内读取超过 200GB 的数据。
但是当我尝试使用其他方法写入 100000 字节时,例如 BufferedOutputStream
同样的过程需要几乎无限长的时间。
造成这种时间差异的原因是什么?有没有更有效的方法来创建n
的文件字节并用 0
填充它是吗?
编辑:如果数据没有真正写入,那么文件是如何填充数据的呢?示例代码:
RandomAccessFile out=new RandomAccessFile("D:/out","rw");
out.seek(100000-1);
out.write(0);
out.close();
这是输出:
另外,如果文件足够大,由于空间不足,我无法再写入磁盘。
最佳答案
当您将 100,000 字节写入 BufferedOutputStream
时,您的程序显式访问文件的每个字节并写入零。
当您使用RandomAccessFile.seek()
时在本地文件上,您间接使用 C 系统调用 fseek()
。如何处理取决于操作系统。
在大多数现代操作系统中,sparse files都支持。这意味着,如果您请求一个空的 100,000 字节文件,则实际上不会使用 100,000 字节的磁盘空间。当您写入字节 100,001 时,操作系统仍然不使用 100,001 字节的磁盘。它为包含“真实”数据的 block 分配少量空间,并单独跟踪空闲空间。
当您读取一个稀疏文件时,例如 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内核源代码来看看稀疏文件是如何实现的,你可以阅读RandomAccessFile
JDK 中的源代码和 JRE 源代码,看看它们如何交互。但是,这可能比您需要的更详细。
关于java - RandomAccessFile.seek() 如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42421768/
如果我们查看 istream 和 ostream 的文档,我们有以下功能: istream& seekg ( streampos pos ); istream& seekg ( streamoff o
如果我想实现 seek() 来完成 SeekableIterator 接口(interface),如果搜索的位置无效,我是否应该在内部恢复到旧位置?像这样: public function seek(
python documentation说: In text files (those opened without a b in the mode string), only seeks relat
我正在编写一个 c++ 方法,需要更新打开文件 (ofstream) 中的一些字符。 该方法获取一个映射作为输入,其中键是一个偏移量(文件中的位置),值是一个字符。 代码示例 typedef map
我注意到,当我做这样的事情时: with open('testfile', 'wb') as fl: fl.seek(2048*512) fl.write(b'aaaaa') 无论我的
我正在开发一个 android 应用程序,我想在状态栏中添加音量控制。我可以在状态栏中添加一个搜索栏吗? 我使用过 NotificationManager,我发现在通知栏中添加动画很困难。 但是任何人
我注意到,当我做这样的事情时: with open('testfile', 'wb') as fl: fl.seek(2048*512) fl.write(b'aaaaa') 无论我的
Python seek()函数:设定读写位置 可以使用 seek() 函数调整当前读写文件的位置。例如,我们从文件头部读取了 1000 个字节,处理这 1000 个字节后发现还有一个很重要的信息在文件
我在 Delphi 2006 中使用 TFileStream。当我使用超出范围的偏移量调用 TFileStream.Seek 时,我得到不同的返回值。当我寻找低于流开头的位置时,该函数返回 -1,如果
我们刚刚在 Delphi 2007 中遇到了 TFileStream.Seek 的一种特殊行为(实际上该方法是从 THandleStream 继承的): 您可以在没有错误的情况下查找文件末尾之外的内容
这是取自 https://forums.embarcadero.com/message.jspa?messageID=219481 的代码片段 if FileExists(dstFile) then
我有一个电子表格,其中包含大量输入,但只有一个输出(价格)。 我想让 Excel 自动更新其中一个输入(称为输入 1),以便在调整其他输入的同时保持价格不变。 我知道“目标搜索”可以做到这一点,但我不
根据 API ,这些是事实: seek(long bytePosition)方法简单来说就是将指针移动到用 bytePosition 指定的位置参数。 当 bytePosition大于文件长度,则文件
我们正在使用 StreamingKit (https://github.com/tumtumtum/StreamingKit) 从流式 m4a 音频源列表中播放,用户可以在这些音频源之间自由来回移动。
我有一个程序可以替换文件中的内容。但是却导致了IO异常,我不知道我哪里逻辑错了? 代码如下: import java.io.File; import java.io.RandomAccessFile;
我想从Excel中导出数据 我尝试下面的代码 def exel_all_attendance(request,course_id): all_submit_attendance = Submi
我正在尝试使用 FileStream。寻求快速跳转到一行并阅读它。 但是,我没有得到正确的结果。我试图看这个有一段时间了,但不明白我做错了什么。 环境: 操作系统:Windows 7 架构:.NET
我正在处理大文件,从 10Gb 开始。我正在将文件的各个部分加载到内存中进行处理。以下代码适用于较小的文件 (700Mb) byte[] byteArr = new byte[layerPixelC
我有一个 for 循环,它被设计为接受一个目标数字,并循环遍历堆栈,直到它在堆栈 [target] 中找到数据并且它应该返回该数据。 不幸的是,我只能让它返回它所在的数组的位置或一串随机数字(随着我的
我创建了一个包含以下条目的文件,由 file.read() 返回 'abcd\nefgh\n1234\nijkl\n5678\n\nend' 我现在打开要阅读的文件,使用“f”作为处理程序。f.rea
我是一名优秀的程序员,十分优秀!