在Ruby中逐字节读取二进制文件

5

我目前正在尝试以块的方式读取二进制文件,我的解决方案如下:

first_portion = File.binread(replay_file, 20)
second_portion = File.binread(replay_file, 24, 20)

第一个数字表示要读取的字节数,第二个数字是偏移量。

我知道这样做不好,因为File.binread在返回后每次都会关闭文件。我应该如何打开文件一次,进行所需操作,完成后关闭它(但仍然使用binread)。

另外,还有一个小问题。我一直在看一些Python示例,并看到了这个:

UINT32 = 'uintle:32'

length = binary_file.read(UINT32)
content = binary_file.read(8 * length)

这到底是在做什么(它是如何工作的),这在Ruby中会是什么样子?
1个回答

5
你可以使用 #read#seek 方法以块的形式打开文件并读取字节:
File.open(replay_file) do |file|
  first_portion = file.read(20)
  file.seek(24, IO::SEEK_END)
  second_portion = file.read(20)
end

文件在end中自动关闭。
关于第二个问题,我不是Python专家,如果我错了,希望有人能纠正我一下,但是在Ruby中应该是这样的:
length = binary_file.read(4).unpack('N').first
# 32 bits = 4 bytes
# i.e., read 4 bytes, convert to a 32 bit integer,
# fetch the first element of the array (unpack always returns an array)

content = binary_file.read(8 * length)
# pretty much verbatim

您可以在这里查看更多选项:String#unpack。该页面提供了更多有关字符串解包的信息。

谢谢,你非常有帮助。 - Fianite
一个快速的问题,如果我处理UINT64或FLOAT32,第二个答案中的第一行会如何改变? UINT64将是8个字节,FLOAT32将是4个字节,这是唯一的区别吗?另外,为什么需要第一个? - Fianite
对于FLOAT32,请使用“'g'”,对于UINT64,请使用“'Q>'”。我在我的答案中添加了“#unpack”的链接供您查看。 - Silver Phoenix
抱歉,我错过了你的另一个问题。#unpack 总是返回一个数组,所以你需要获取数组的 第一个 元素。 - Silver Phoenix
1
你也可以使用String#unpack1代替.unpack(...).first - Alex Gittemeier
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接