# Reading byte-aligned struct from binary file

**URL:** <https://discourse.julialang.org/t/reading-byte-aligned-struct-from-binary-file/59323>\
**Category:** New to Julia\
**Tags:** binaryio\
**Created:** [April 15, 2021, 9:26am UTC](https://discourse.julialang.org/t/reading-byte-aligned-struct-from-binary-file/59323 "2021-04-15T09:26:01Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![GeraldJansen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/geraldjansen/32/24065_2.png) [@GeraldJansen](https://discourse.julialang.org/u/GeraldJansen)\
**Post date:** [April 15, 2021, 9:26am UTC](https://discourse.julialang.org/t/reading-byte-aligned-struct-from-binary-file/59323/1 "2021-04-15T09:26:01Z")

</div>

I need to read data from a binary file created by a C program using a byte-aligned struct. Below is a reduced version of the C program and my best effort at reading the binary file in Julia.

```julia
#include <stdio.h>
typedef struct {
  char fill;
  char sex;
  short days;
  char breed[2];
} PedInfo;
void main()
{
  PedInfo p;
  int i;
  FILE *f;
  f = fopen("test.bin", "w");
  for (i=1; i<=3; i++) {
    p.fill = ' ';
    p.sex = "MF"[i%2];
    p.days = i * 1111;
    p.breed[0] = "HJA"[i%3];
    p.breed[1] = "OEY"[i%3];
    fwrite(&p.sex, 1, 5, f); // misalignment created here!
  }
  fclose(f);
}

```

Here’s my ugly Julia program

```julia
using Printf
buf = zeros(UInt8, 5)
buf2 = zeros(UInt8, 2)
open("test.bin", "r") do f
    for i in 1:3
        read!(f, buf)
        sex = Char(buf[1])
        buf2[1:2] = buf[2:3]
        days = reinterpret(Int16, buf2)[1]
        breed = String(buf[4:5])
        @printf("%d %c %hd %s\n", i, sex, days, breed)
    end
end

```

with correct output

```julia
1 F 1111 JE
2 M 2222 AY
3 F 3333 HO

```

Is there a better/nicer way to read this binary file in Julia?

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 15, 2021, 11:57am UTC](https://discourse.julialang.org/t/reading-byte-aligned-struct-from-binary-file/59323/2 "2021-04-15T11:57:07Z")

</div>

You could to something like

```julia
julia> struct Foo
         fill::Cchar
         sex::Cchar
         days::Int16
         breed::Tuple{Cchar, Cchar}
       end

julia> Base.show(io::IO, f::Foo) = print(io, Char(f.sex), ' ', f.days, ' ', Char(f.breed[1]), Char(f.breed[2]))

julia> buf = zeros(UInt8, 6);

julia> open("test.bin", "r") do io
         for i in 1:3
           read!(io, @view(buf[2:6]))
           println(i, ": ", reinterpret(Foo, buf)[1])
         end
       end
1: F 1111 JE
2: M 2222 AY
3: F 3333 HO

```

or even

```julia
julia> function readfile(file)
         open(file, "r") do io
           out = zeros(UInt8, 18) 
           for i in 0:2
             read!(io, @view(out[6i .+ (2:6)]))
           end
           reinterpret(Foo, out)
         end
       end
readfile (generic function with 1 method)

julia> readfile("test.bin")
3-element reinterpret(Foo, ::Vector{UInt8}):
 F 1111 JE
 M 2222 AY
 F 3333 HO

```

---

<div class="post-metadata">

**Author:** ![GeraldJansen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/geraldjansen/32/24065_2.png) [@GeraldJansen](https://discourse.julialang.org/u/GeraldJansen)\
**Post date:** [April 15, 2021, 1:08pm UTC](https://discourse.julialang.org/t/reading-byte-aligned-struct-from-binary-file/59323/3 "2021-04-15T13:08:05Z")

</div>

Thanks much! The first part of your answer contains all the elements I need (Struct with Cchar and  
Tuple{Cchar, Cchar} and the @view) to move forward. In my case the file has 85 million records and many more fields in the struct, so I don’t want to slurp it all into memory as in your second example. However, that approach could be useful in other cases.
