# Importing a binary file to a struct

**URL:** <https://discourse.julialang.org/t/importing-a-binary-file-to-a-struct/49629>\
**Category:** New to Julia\
**Tags:** question, binaryio\
**Created:** [November 5, 2020, 2:11pm UTC](https://discourse.julialang.org/t/importing-a-binary-file-to-a-struct/49629 "2020-11-05T14:11:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![DTL](https://avatars.discourse-cdn.com/v4/letter/d/90ced4/32.png) [@DTL](https://discourse.julialang.org/u/DTL)\
**Post date:** [November 5, 2020, 2:11pm UTC](https://discourse.julialang.org/t/importing-a-binary-file-to-a-struct/49629/1 "2020-11-05T14:11:20Z")

</div>

Hi,  
I’m trying to port over some C++ & IDL code to Julia, the code basically opens up a binary file which has a 512 byte header described by a c++ struct. The reaminder of the file is a stack of 8-bit greyscale images, the details of the stack are given in elements of the header.  
I can create a struct in Julia to hold the header data, but trying to read in the file fails. This is the code I’m trying.  
`
mutable struct tomheader
xsize::UInt16
ysize::UInt16
zsize::UInt16
lmarg::UInt16
rmarg::UInt16
tmarg::UInt16
bmarg::UInt16
tzmarg::UInt16
bzmarg::UInt16
num_samples::UInt16
num_proj::UInt16
num_blocks::UInt16
num_slices::UInt16
bin::UInt16
gain::UInt16
speed::UInt16
pepper::UInt16
calibrationissue::UInt16
num_frames::UInt16
machine::UInt16
spare_int::Array{UInt16,12}
scale::Float32
offset::Float32
voltage::Float32
current::Float32
thickness::Float32
pixel_size::Float32
distance::Float32
exposure::Float32
mag_factor::Float32
filterb::Float32
correction_factor::Float32
spare_float::Array{Float32,2}
z_shift::UInt32
z::UInt32
theta::UInt32
time::Array{UInt8,26}
duration::Array{UInt8,12}
owner::Array{UInt8,21}
user::Array{UInt8,5}
specimen::Array{UInt8,32}
scan::Array{UInt8,32}
comment::Array{UInt8,64}
spare_char::Array{UInt8,192}
end`

`
`

`f = open(“testfile.tom”,“r”)
th = Ref{tomheader}() // fails with Base.RefValue{tomheader}(#undef)
read!(f, th,512)
`

Can anyone point me at what I’m doing wrong?

cheers,  
David

---

<div class="post-metadata">

**Author:** ![WschW](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wschw/32/6575_2.png) [@WschW](https://discourse.julialang.org/u/WschW)\
**Post date:** [November 5, 2020, 2:41pm UTC](https://discourse.julialang.org/t/importing-a-binary-file-to-a-struct/49629/2 "2020-11-05T14:41:01Z")

</div>

Unless the C++ code is using Julia arrays you are using the wrong types, for example:  
`Array{UInt8,192}`  
This is a 192 dimensional Julia array. If the c code you are using specifies `unsigned char[192]` then the corresponding type is `NTuple{192, Uint8}` instead.

I don’t do much C interop, but I think you should be using a plain struct rather then a mutable one.

I am on my phone and don’t have a compiler to test with but assuming you made the above changes then

```julia
buffer = Vector{Uint8}(undef, 512)
readbytes!(f, buffer, 512)
th = reinterpret(tomheader, buffer)[1]

```

should do what you are trying to do.

edit: added undef

---

<div class="post-metadata">

**Author:** ![DTL](https://avatars.discourse-cdn.com/v4/letter/d/90ced4/32.png) [@DTL](https://discourse.julialang.org/u/DTL)\
**Post date:** [November 5, 2020, 3:19pm UTC](https://discourse.julialang.org/t/importing-a-binary-file-to-a-struct/49629/3 "2020-11-05T15:19:12Z")

</div>

> [@WschW](#):
>
> `readbytes!(f, buffer, 512)`

Thank you for the pointer on not needing mutable struct and NTuple for an array of bytes.  
It almost works!  
I had to add a , to the buffer setup to make it  
`
buffer = Vector{UInt8},(512)
` It only produced an error otherwise.  
Attempting the readbytes line gives the following:  
`
MethodError: no method matching readbytes!(::IOStream, ::Tuple{DataType,Int64}, ::Int64)
Closest candidates are:
readbytes!(::IOStream, !Matched::Array{UInt8,N} where N, ::Any; all) at iostream.jl:484
readbytes!(::IO, !Matched::AbstractArray{UInt8,N} where N, ::Any) at io.jl:913
readbytes!(::IOStream, !Matched::Array{UInt8,N} where N) at iostream.jl:484`

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [November 5, 2020, 4:15pm UTC](https://discourse.julialang.org/t/importing-a-binary-file-to-a-struct/49629/4 "2020-11-05T16:15:29Z")

</div>

`buffer = Vector{UInt8},(512)` - That won’t really work. It’ll just make `buffer` a tuple of the `Vector{UInt8}` type as the first element, and the integer `512` as the second.  
To initialize an empty array of length 512, use `Vector{UInt8}(undef, 512)`.

Some code that loads your type from the first 512 bytes of a file may look like:

```julia
open("my_file.txt") do file
    buffer = Vector{UInt8}(undef, 512)
    readbytes!(file, buffer)
    return reinterpret(TomHeader, buffer)[1]
end

```
