我在一些ruby代码中使用了一个不透明的API,它以File / IO作为参数。我希望能够传递一个IO对象,该对象只能访问真实IO对象中给定范围的数据。
例如,我有一个8GB的文件,我想给api一个在我的真实文件中间有1GB范围的IO对象。
real_file = File.new('my-big-file')
offset = 1 * 2**30 # start 1 GB into it
length = 1 * 2**30 # end 1 GB after start
filter = IOFilter.new(real_file, offset, length)
# The api only sees the 1GB of data in the middle
opaque_api(filter)
filter_io项目看起来最容易适应这一点,但似乎并不直接支持这个用例。
答案 0 :(得分:1)
我认为你必须自己编写,因为它似乎是一个相当具体的事情:你必须使用一大块来实现IO
方法的所有(或者你需要的子集)打开的文件作为数据源。 “专业”的一个例子是写入这样的流 - 你必须注意不要跨越给定段的边界,即不断跟踪你在大文件中的当前位置。看起来不是一件微不足道的工作,而且我没有看到任何可以帮助你的捷径。
也许您可以找到一些基于操作系统的解决方案,例如将环回设备从大文件的部分中取出(例如,请参阅man losetup
,尤其是-o
和--sizelimit
选项。
变式2:
如果您可以随时将窗口内容保存在内存中,可以像这样包装StringIO
(只是草图,未经测试):
def sliding_io filename, offset, length
File.open(filename, 'r+') do |f|
# read the window into a buffer
f.seek(offset)
buf = f.read(length)
# wrap a buffer into StringIO and pass it given block
StringIO.open(buf) do |buf_io|
yield(buf_io)
end
# write altered buffer back to the big file
f.seek(offset)
f.write(buf[0,length])
end
end
并使用它,就像使用IO#open
的块变体一样。
答案 1 :(得分:0)
我相信IO对象具有您正在寻找的功能。我之前使用过MD5哈希求和类似大小的文件。
incr_digest = Digest::MD5.new()
file = File.open(filename, 'rb') do |io|
while chunk = io.read(50000)
incr_digest << chunk
end
end
这是我使用的块,我将块传递给MD5 Digest对象。