Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 如何开始读取二进制数据中的偏移量?_Ruby_Binary Data_Bindata - Fatal编程技术网

Ruby 如何开始读取二进制数据中的偏移量?

Ruby 如何开始读取二进制数据中的偏移量?,ruby,binary-data,bindata,Ruby,Binary Data,Bindata,我有一个类似C的结构,如下所示: SomeStruct << BinData::Record endian :little uint32 :offsetOfName uint32 :offsetOfLastname #... uint32 :lenVars struct :Person, :length => :lenVars string :name string :lname #... end SomeStruct:lenVars 字符串:名称

我有一个类似C的结构,如下所示:

SomeStruct << BinData::Record
endian :little

uint32 :offsetOfName
uint32 :offsetOfLastname
#...
uint32 :lenVars
struct :Person, :length => :lenVars
    string :name
    string :lname
    #...
end
SomeStruct:lenVars
字符串:名称
字符串:lname
#...
结束
:Person
之前,我有一系列偏移量和长度。所有偏移量和长度都描述了
:Person
结构中的数据


如何在指定的偏移量、给定的长度或直到下一个偏移量开始读取数据?

查找偏移量1234,然后将32字节读入字符串
s:

open 'some-binary-file', 'r' do |f|
  f.seek 1234
  s = f.read 32
  # tho in your case, something like:
  o = aBinData_object.read f
  p s
end
更新:看起来BinData理解对自己字段长度进行编码的记录,但我怀疑是否有任何方法可以让它为您搜索,除非您愿意对虚拟字段进行编码,其大小与搜索到的字段的大小相同,然后永远忽略它跳过的数据

我怀疑一个好的解决方案将涉及显式搜索,然后
someBinDataObject.read(f)
获取记录。

BinData的文档:

不熟悉BinData,因此可能我在这里不太熟悉,但示例似乎为最外层的结构定义了一个类:

class SomeStruct < BinData::Record
...

而且,看起来你给了你的内在结构:person一个长度。我的猜测是长度在这里不适用。

BinData有两个与偏移相关的选项-:check\u offset和:adjust\u offset。这些未记录在手册中,但记录在bindata/offset.rb中

下面是它们如何应用到您的示例中

class SomeStruct < BinData::Record
  endian :little

  uint32 :offsetOfName
  uint32 :offsetOfLastname
  #...
  uint32 :lenVars

  struct :person do
    string :name,  :adjust_offset => :offsetOfName,
                   :read_length => lambda { offsetOfLastName - offsetOfName }
    string :lname, :adjust_offset => :offsetOfLastName,
                   :read_length => ...
    #...
  end
end
class-SomeStruct:offsetOfName,
:read_length=>lambda{offsetOfLastName-offsetOfName}
字符串:lname,:adjust_offset=>:offsetOfLastName,
:read_length=>。。。
#...
结束
结束

我希望能用BinData解决问题,不过还是要谢谢你。我将继续玩一下代码,让您知道结果。@DigitalRoss为什么要将其读入字符串?打开“某个二进制文件”,“r”do | f | f.seek 1234 o=abinda|u object.read f end难道这还不够吗?哦,长度必须保持不变,但实际上没有那么重要。我甚至可以把它拿出来。我已经阅读了几次文档,寻找我需要的东西,但都找不到,所以我在这里求助于麻烦更聪明的人PMy的理解是结构的长度(在c中)是其中基本类型长度的总和。我创建了一个BinData::Struct并尝试获取长度:得到了这个错误:{“a”=>0}的未定义方法`length':BinData::Struct您知道adjust_offset是绝对的还是相对的吗?API文档在这方面确实很缺乏,我查看了源代码,发现它确实是相对的。但是,我需要根据当前文件(io)偏移量调整偏移量。例如-:adjust_offset=>(SOME_CONSTANT-currentOffset)如何访问闭包中文件的当前偏移量(lambda)?
class SomeStruct < BinData::Record
  endian :little

  uint32 :offsetOfName
  uint32 :offsetOfLastname
  #...
  uint32 :lenVars

  struct :person do
    string :name,  :adjust_offset => :offsetOfName,
                   :read_length => lambda { offsetOfLastName - offsetOfName }
    string :lname, :adjust_offset => :offsetOfLastName,
                   :read_length => ...
    #...
  end
end