写入预分配文件的特定部分

Write to specific part of preallocated file

我目前正在尝试写入预分配文件的不同位置。

我首先这样分配了我的文件:

File.open("file", "wb") { |file| file.truncate(size) }

大小是文件的总大小。

之后我收到了适合该文件的 Y 位置的 XX 大小的数据。请记住,这部分过程是分叉的。每个 fork 都有它自己独特的套接字并打开它自己独特的文件句柄,写入文件,然后关闭它。

data = socket.read(256)

File.open("file", "wb") do |output|
   output.seek(location * 256, IO::SEEK_SET)
   output.write(data)
end

这应该反过来允许分叉进程打开文件句柄,寻找正确的位置(如果位置为 2 且 data_size 为 256,则写入位置为 512 -> 768)并写入它收到的数据块。

虽然这是在做什么,超出了我的理解范围。我在填充文件时监视文件大小,并且它从不应该更改的不同文件大小中跳来跳去。

当用十六进制编辑器分析文件时,文件数据头应该在顶部的地方被空字节填充(就像文件的 1/4 一样)。尽管如果我将分叉进程限制为仅写入 1 个文件块然后退出,写入就可以正常进行并位于正确的位置。

我做了一些其他测试,例如转储该部分位置,数据的起始位置和我寻找文件正确位置的等式似乎也是正确的。

这里有什么我遗漏的吗,或者是否有另一种方法可以让多个 threads/processes 打开文件的文件句柄,查找特定位置,然后写入一大块数据?

我也尝试过在文件上使用 FLOCK,它产生了相同的结果,同样使用主进程而不是分叉。


我已经测试了同一个应用程序,但是每次我需要快速连续写入数据(传输速度接近 70mb/s)时,我没有 opening/closing 文件句柄,而是为每个分叉进程创建一个文件句柄并保持开放。这解决了导致 1:1 具有匹配校验和的文件重复的问题。

所以问题是,为什么 opening/writing/closing 文件句柄快速连续地导致此行为?

这是你的文件模式。

File.open("file", "wb")

"wb" 表示 "upon opening, truncate the file to zero length".

我建议"r+b",也就是"reading and writing, no truncation"。在此处阅读有关可用模式的更多信息:http://ruby-doc.org/core-2.2.2/IO.html#method-c-new

顺便说一句,"b" 在这些模式下意味着 "binary"(与默认 "t"(文本)相反)