Readline() and end-of-file

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

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?

You can iterate over eachline:

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.

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

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:

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).

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

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

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

1 Like

What about:

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
2 Likes

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.

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