Is there a way to slice an `IOStream`?

I have an IOStream, and I only want to read between the mth line and nth line. How should I do?
I have a pseudocode:

using ResumableFunctions

@resumable function iterate_io_between(io::IOStream, m::Int, n::Int)
    io = seek(io, m)
    while pos != n
        pos = position(io)
        @yield io
    end
end

I am not sure the @yield statement works, since I have not used ResumableFunctions before.

seek operates on byte offsets but it seems you want m and n to be lines. You can use readline until you get to line m and n respectively. There is no way to immediately “jump” to the correct line in a file.

1 Like

Thanks. You are right. But then I am still confused about how to write the code. How should I “start” "yield"ing the IOStream at the mth line and stop it at the nth line? Like this?

@resumable function iterate_io_between(io::IOStream, start::Int, stop::Int)
    for i in eachindex(1:stop)
        if i == start
            @yield io
        else
            continue
        end  # if-else
    end  # for
end

Do you necessarily have to use ResumableFunctions? You could just compose some iterators:

shell> cat file
1
2
3
4
5

julia> iterate_io_between(io, start, stop) = Iterators.take(Iterators.drop(eachline(io), start - 1), stop - start + 1)
iterate_io_between (generic function with 1 method)

julia> iter = iterate_io_between(open("file", "r"), 2, 4);

julia> collect(iter)
3-element Array{String,1}:
 "2"
 "3"
 "4"
1 Like

Thank you for your help. The reason why I want to use ResumableFunctions is that I want the return type of iterate_io_between is also an IOStream. If I am using your solution, then the type will be a Base.Iterators.Take.