Skip to content

Add methods for filling a buffer from an IO greedily/lazily #14605

@BlobCodes

Description

@BlobCodes

Feature Request

IO#read currently makes very few assumptions about the amount of data that must be read (only that 0 bytes returned = EOF).
This can be cumbersome when writing methods which process IO data.

Because of this, lots of code currently makes the assumption that IO#read fills the entire buffer if enough data is available (ex. #14604).
The only methods which currently allow reading greedily (#read_fully, #read_fully?) do not return the amount of bytes read if the buffer was not filled entirely, causing the remaining bytes to be lost if the IO does not implement #pos.

Therefore, I think it would be useful to add a separate method with this behaviour:

# Similar to `#read`, but with the additional guarantee that either
# the buffer will be entirely filled or the EOF will be reached while trying.
#
# Calling this method may result in multiple read calls if necessary.
def read_greedy(slice : Bytes) : Int32
  count = slice.size
  while slice.size > 0
    read_bytes = read(slice)
    return count &- slice.size if read_bytes == 0
    slice += read_bytes
  end
  count
end

Adding this as a separate method allows many IOs which already have this behavior implicitly (ex. IO::Memory) to implement it more efficiently while ensuring correctness for IOs which do not have this behavior.


Additionally, as an opposite counterpart, it may be useful to add a method (IO#read_lazy ?) for reading from an IO lazily (ex. non-blocking read from STDIN which simply returns 0 if there was no user input without concurrency).

Metadata

Metadata

Assignees

No one assigned

    Labels

    good first issueThis is an issue suited for newcomers to become aquianted with working on the codebase.help wantedThis issue is generally accepted and needs someone to pick it upkind:featuretopic:stdlib:files

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions