Unpack Binary Data with specific format in Julia

Viewed 269

I am trying to convert a Binary file parser to Julia from Python. I am struggling to figure out how to unpack the binary stream with a specific format. I found this discourse thread that is exactly what I am trying to do, but its from 2017 and doesn't seem to have a working solution. Does anyone have a solution?

In Python it looks like this:

In [22]: struct.unpack('>idi', b'\x00\x00\x00\x17@\t\x1e\xb8Q\xeb\x85\x1f\x00\x00\x00*')
Out[22]: (23, 3.14, 42)

In Julia I am here:

data = open(filename, "r")
seek(data, 0)
# now I want to get the first 12 bytes of the file and convert to a string.. and am stumped.. 
1 Answers

I'm not very familiar with struct.unpack in Python, but maybe you could do something like this:

julia> data = IOBuffer("\x00\x00\x00\x17@\t\x1e\xb8Q\xeb\x85\x1f\x00\x00\x00*")
IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=16, maxsize=Inf, ptr=1, mark=-1)

julia> seekstart(data)
IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=16, maxsize=Inf, ptr=1, mark=-1)

julia> i  = bswap(read(data, Int32))
23

julia> pi = bswap(read(data, Float64))
3.14

julia> i  = bswap(read(data, Int32))
42

bswaps are there because there seems to be a difference in endianness between what Julia internally uses and what's encoded in your binary stream. Apart from that, this is just a plain use of read, specifying the type of data to be read.

By the way, here is how you would read the first 12 bytes of the file, and convert them to a string (which is not really necessary in this case, but could be useful in others):

julia> seekstart(data)
IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=16, maxsize=Inf, ptr=1, mark=-1)

julia> bytes = read(data, 12)
12-element Array{UInt8,1}:
 0x00
 0x00
 0x00
 0x17
 0x40
 0x09
 0x1e
 0xb8
 0x51
 0xeb
 0x85
 0x1f

# note the capital "S" in "String"
julia> String(bytes)
"\0\0\0\x17@\t\x1e\xb8Q\xeb\x85\x1f"
Related