-1

I'm trying to work with .bin file of specific format. I know exactly the type and place of each element in this bin. Is there any elegant way of reading such files?

In Python I can do it using struct module. But I use R for my application and it's highly undesirable to use another programming language.

My Python code:

import struct
 
struct_fmt = '=HHHHHHH80h80hhhhffff20fhh4fHHH5h' # int[5], float, byte[255]
struct_len = struct.calcsize(struct_fmt)
struct_unpack = struct.Struct(struct_fmt).unpack_from
 
results = []
with open("14.09.20-23.52.55.292.bin", "rb") as f:
    while True:
        data = f.read(struct_len)
        if not data: break
        s = struct_unpack(data)
        results.append(s)

I came across some doubtful ways, but I wonder if there is a more elegant variant.

SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41
  • It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Oct 29 '20 at 20:04
  • You're right, sorry :) Link to bin file: [here](https://drive.google.com/file/d/1uMbhQBUcQn8S3CS41NdYAJPK885KIQx3/view?usp=sharing) Link to result file: [here](https://drive.google.com/file/d/1k-8N8Q5OR5bzOrPeVawe1VnA--HlSnjd/view?usp=sharing) – Андрон Алексанян Oct 29 '20 at 20:25

1 Answers1

0

Translating those to R commands would look like this

con <- file("14.09.20-23.52.55.292.bin", "rb")
list(
  readBin(con, integer(), 7, 2, FALSE), #HHHHHHH
  readBin(con, integer(), 80, 2, TRUE), # 80h
  readBin(con, integer(), 80, 2, TRUE), # 80h
  readBin(con, integer(), 3, 2, TRUE),  # hhh
  readBin(con, numeric(), 4, 4, TRUE), # ffff
  readBin(con, numeric(), 20, 4, TRUE), # 20f
  readBin(con, integer(), 2, 2, TRUE), # hh
  readBin(con, numeric(), 4, 4, TRUE), # 4f
  readBin(con, integer(), 3, 2, FALSE), # HHH
  readBin(con, integer(), 5, 2, TRUE) # 5h
)
close(con)

It's not exactly "elegant". You could easily write a function to clean things up but that would kind of depend on how you want to store all these values. Here I've just thrown them in a list

MrFlick
  • 195,160
  • 17
  • 277
  • 295