# Binary-read fixed-length String

**URL:** <https://discourse.julialang.org/t/binary-read-fixed-length-string/66080>\
**Category:** New to Julia\
**Tags:** question, binaryio\
**Created:** [August 9, 2021, 3:25pm UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080 "2021-08-09T15:25:39Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 9, 2021, 3:25pm UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/1 "2021-08-09T15:25:39Z")

</div>

I was wondering how to read a fixed-length character string from a binary file. My file is formatted like this:

```julia
Int32|4-byte string|array of Float32's . . . 

```

The string consists of just four plain ASCII characters without null termination.

So far, I’ve been successful in reading the first integer

```julia
open("datafile.dat", "r") do io
  header = read(io, Int32)
  println(header)
  str = read(io, 4) # four-byte string
  println(str)
end

```

For the string, I get a Vector{UInt8}. So, how do you convert it to a String?

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [August 9, 2021, 3:41pm UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/2 "2021-08-09T15:41:51Z")

</div>

Example:

```julia
julia> v=UInt8[0x54,0x68,0x69,0x73]
4-element Vector{UInt8}:
 0x54
 0x68
 0x69
 0x73

julia> join(Array{Char}(v))
"This"

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 9, 2021, 4:01pm UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/3 "2021-08-09T16:01:14Z")

</div>

even simpler:

```julia
julia> v=UInt8[0x54,0x68,0x69,0x73]
4-element Vector{UInt8}:
 0x54
 0x68
 0x69
 0x73

julia> String(v) # just return this
"This"

julia> v
UInt8[]

```

this is non-copy

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [August 9, 2021, 5:24pm UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/4 "2021-08-09T17:24:36Z")

</div>

Oh, wow… hmm, my example is from an older code of mine, has something changed from an earlier version? Or did I just missed how easy it can be? Probably the last 😉

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 11, 2021, 5:27pm UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/5 "2021-08-11T17:27:17Z")

</div>

Thank you both for the solutions!

* * *

I’m finding that Julia’s binary reading isn’t as simple as Fortran’s. The datafile I’m reading was actually created by a Fortran program. To read it in Fortran, it’s just

```fortran
integer:: iflag
character(4):: str
real(8):: arr(100,200)
open(newunit=uni, access="STREAM", . . .)
read(uni) iflag, str, arr

```

while Julia uses at least three different methods:

```julia
iflag = read(io, Int32)
str = String(read(io, 4)) # four-byte string
arr = Array{Float32}(undef, (100,200))
read!(io,arr)

```

So, I was wondering if it’s possible to write a generic binary-read function, `read_bin!(v...)`, which can read objects of simple types:

```julia
iflag::Int32 = 0
str::String = ""
arr = Array{Float32}(undef, (100,200))
read_bin!(io, iflag, (str, 4), arr)

```

or

```julia
iflag, str, arr = read_bin(io, Int32, (String, 4), (Array{Float32, 2}, (100, 200)) )

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 11, 2021, 5:46pm UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/6 "2021-08-11T17:46:08Z")

</div>

> [@ryofurue](#):
>
> while Julia uses at least three different methods:

those two seems to contain same amount of typing while Julia doesn’t have random things like `newunit=uni, access="STREAM"` then somehow `uni` is now a variable and also config is done by remembering string? (I speak eps() Fortran sorry)

Btw in case you like this better:

```julia
iflag = read(io, Int32)
str = String(read(io, 4)) # four-byte string
arr = reshape(reinterpret(Float32, read(io)), 100, 200)

```

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [August 11, 2021, 7:05pm UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/7 "2021-08-11T19:05:19Z")

</div>

Like @jling says reading strings is pretty ok

```julia
str = String(read(io, 4)) # four-byte string

```

Reading Arrays seems too hard, on the other hand.  
I have openned [https://github.com/JuliaLang/julia/issues/41865](https://github.com/JuliaLang/julia/issues/41865)

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [August 12, 2021, 3:14am UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/8 "2021-08-12T03:14:40Z")

</div>

> those two seems to contain same amount of typing while Julia doesn’t have random things like newunit=uni, access=“STREAM”

When I said “at least three different methods”, I didn’t mean the amount of typing. I meant _inconsistency_. In addition to the three ways, now `reshape` and `reinterpret` have been thrown in.

You have to learn several different things to do “the same” thing.

In Fortran, `newunit` and `access` are regular parts of the `open` statement. You consistently use them.

So, I appreciate the efforts of @oxinabox to bring some consistency.

As he/she discusses in the other thread, this user interface

```julia
iflag = read(io, Int32)

```

is desirable for Arrays, too.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [August 12, 2021, 8:34am UTC](https://discourse.julialang.org/t/binary-read-fixed-length-string/66080/9 "2021-08-12T08:34:03Z")

</div>

> [@ryofurue](#):
>
> I meant _inconsistency_ .

I mean you’re just moving `4` and `String` to different places, language will need that information anyway, in Julia, String is not a vector of Chars (think Unicodes…) so you need to read 4 bytes first and then say: it’s a String.

Similarly for Array, the data in file is not 2D and grouped in bytes, so you will need an order, now it happens to be the in-file order is the same as in-memory order (column major), but again, it’s not guaranteed, imagine the file is output by Numpy.

I agree it will be easier if we have a:

```julia
read(io, Vector{T}, n)

```

but the shape info, you will have to deal with it.
