# Readline() and end-of-file

**URL:** <https://discourse.julialang.org/t/readline-and-end-of-file/64384>\
**Category:** New to Julia\
**Tags:** io\
**Created:** [July 9, 2021, 8:08pm UTC](https://discourse.julialang.org/t/readline-and-end-of-file/64384 "2021-07-09T20:08:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 9, 2021, 8:08pm UTC](https://discourse.julialang.org/t/readline-and-end-of-file/64384/1 "2021-07-09T20:08:09Z")

</div>

I need to read a file with a loop that is something like this:

```julia
file = open("file.txt","r")
while true
   length(readline(file)) == 0 && break # ignore this line and exit if file ended??
   for i in 1:n
      line = readline(file) # do stuff with this line
   end
end
close(file)

```

initially I thought that `readline()` would error at the end of the file, but it returns an empty string `""`, and that is why I added the test of the length of the output of `readline()` to exit the loop.

If there was an empty line in the middle of the file, the loop would exit prematurely. One alternative is to use `readline(file,keep=true)`, in which case the `\n` characters are kept and `length(line) == 1`. Would you recommend this? Is there some better way to detect the end of the file?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [July 9, 2021, 8:30pm UTC](https://discourse.julialang.org/t/readline-and-end-of-file/64384/2 "2021-07-09T20:30:05Z")

</div>

You can iterate over `eachline`:

> ```julia
> julia> open("my_file.txt", "w") do io
> write(io, "JuliaLang is a GitHub organization.\n It has many members.\n");
> end;
> 
> julia> for line in eachline("my_file.txt")
> print(line)
> end
> JuliaLang is a GitHub organization. It has many members.
> 
> ```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 9, 2021, 8:37pm UTC](https://discourse.julialang.org/t/readline-and-end-of-file/64384/3 "2021-07-09T20:37:21Z")

</div>

Yes, I know, but I don’t see immediately how I could use that in this case. The file is something like:

```julia
3 (number of data points in next block)
comment
1 data line 1
2 data line 2 
3 data line 3
3 (number of data points in next block)
comment
1 data line 1
2 data line 2 
3 data line 3

```

and that is why I am reading with that structure (ignoring two lines, then reading the data in an inner loop).

I mean, I could do something awkward like, but seem very cumbersome:

```julia
skiplines = 0
idata = 0
for line in eachline(file)
  skiplines += 1
  if skipelines > 3
    idata += 1
    # read data
  end
  if idata == ndata
    skiplines == 0
    idata == 0
  end
end

```

(something like that).

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [July 9, 2021, 9:21pm UTC](https://discourse.julialang.org/t/readline-and-end-of-file/64384/4 "2021-07-09T21:21:56Z")

</div>

> [@lmiq](#):
>
> but I don’t see immediately how I could use that in this case

With the information provided in your first message I’d have simply done

```julia
for line in eachline(file)
    # do stuff with this line
end

```

> [@lmiq](#):
>
> I mean, I could do something awkward like, but seem very cumbersome:

How that would be different with your original approach? I must be missing something obvious?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [July 9, 2021, 10:09pm UTC](https://discourse.julialang.org/t/readline-and-end-of-file/64384/5 "2021-07-09T22:09:21Z")

</div>

What about:

```julia
data = []
open(file) do io
    while !eof(io)
        n = parse(Int,readline(io))
        println(readline(io))
        for i in 1:n
            push!(data, parse.(Float64, split(readline(io))))
        end
    end
end

# code above tested alright on ascii file input:
3
comment1
0.0 1.1
0.5 2.0
1.0 3.2
3
comment2
1.0 3.1
2.5 1.0
3.0 0.2

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 9, 2021, 10:09pm UTC](https://discourse.julialang.org/t/readline-and-end-of-file/64384/6 "2021-07-09T22:09:50Z")

</div>

Sorry, I will post something more specific and clear asap.

The difference is relying on the return value of `readline()` or not to decide if the file is ended.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [July 9, 2021, 10:10pm UTC](https://discourse.julialang.org/t/readline-and-end-of-file/64384/7 "2021-07-09T22:10:59Z")

</div>

> [@rafael.guerra](#):
>
> `eof(io)`

probably this is the function I need. Thanks. I will check that.
