Reference
BufferIO.AbstractBufReader — Type
abstract type AbstractBufReader endAn AbstractBufReader is a readable IO type that exposes a buffer of readable bytes to the user.
By default, subtypes of AbstractBufReader are not threadsafe, so concurrent usage should protect the instance behind a lock.
Extended help
Subtypes of this type should not have a zero-sized buffer which cannot expand when calling fill_buffer.
Subtypes T of this type should implement at least:
get_buffer(io::T)fill_buffer(io::T)consume(io::T, n::Int)Base.close(io::T)
Subtypes may optionally define the following methods. See their docstring for BufReader / BufWriter for details of the implementation:
Base.seek(io::T, ::Int)relative_seek(io::T, ::Int)Base.filesize(io::T)Base.position(io::T)resize_buffer(io::T, ::Int)
AbstractBufReaders have implementations for many Base IO methods, but with more precisely specified semantics than for Base.IO. See docstrings of the specific functions of interest.
BufferIO.AbstractBufWriter — Type
abstract type AbstractBufWriter endAn AbstractBufWriter is an IO-like type which exposes mutable memory to the user, which can be written to directly. This can help avoiding intermediate allocations when writing. For example, integers can usually be written to buffered writers without allocating.
By default, subtypes of AbstractBufWriter are not threadsafe, so concurrent usage should protect the instance behind a lock.
Extended help
Subtypes of this type should not have a zero-sized buffer which cannot expand when calling grow_buffer.
Subtypes T of this type should implement at least:
get_buffer(io::T)grow_buffer(io::T)consume(io::T, n::Int)Base.close(io::T)Base.flush(io::T)
They may optionally implement
Base.seek(io::T, ::Int)Base.filesize(io::T)Base.position(io::T)get_unflushed(io::T)shallow_flush(io::T)resize_buffer(io::T, ::Int)get_nonempty_buffer(io::T, ::Int)
BufferIO.BufReader — Type
BufReader(f, io::IO, [buffer_size::Int])Create a BufReader wrapping io, then call f on the BufReader, and close the reader once f is finished or if it errors.
This pattern is useful for automatically cleaning up the resource of io.
julia> io = IOBuffer("hello world");
julia> BufReader(io) do reader
println(String(read(io, 5)))
end
hello
julia> read(io) # closing reader closes io also
ERROR: ArgumentError: read failed, IOBuffer is not readable
[...]BufferIO.BufReader — Type
BufReader{T <: IO} <: AbstractBufReader
BufReader(io::IO, [buffer_size::Int])::BufReaderWrap an IO in a struct with a new buffer, giving it the AbstractBufReader interface.
The BufReader has an infinitely growable buffer, and will only grow the buffer if fill_buffer is called while its internal buffer is full.
This wrapper reads from io using readbytes!. If io is not EOF, and readbytes! reads zero bytes, an exception is thrown when filling the buffer.
Throw an ArgumentError if buffer_size is less than 1.
julia> rdr = BufReader(IOBuffer("Hello, world!\nabc\r\ndef"));
julia> get_buffer(rdr) |> isempty
true
julia> peek(rdr)
0x48
julia> readline(rdr)
"Hello, world!"
julia> String(readavailable(rdr))
"abc\r\ndef"BufferIO.BufWriter — Type
BufWriter(f, io::IO, [buffer_size::Int])Create a BufWriter wrapping io, then call f on the BufWriter, and close the writer once f is finished or if it errors.
This pattern is useful for automatically cleaning up the resource of io.
julia> io = IOBuffer();
julia> BufWriter(io) do writer
write(writer, "hello, world!")
shallow_flush(writer)
seekstart(io)
println(String(read(io)))
end
hello, world!
julia> iswritable(io) # closing writer closes io also
falseBufferIO.BufWriter — Type
BufWriter{T <: IO} <: AbstractBufWriter
BufWriter(io::IO, [buffer_size::Int])::BufWriterWrap an IO in a struct with a new buffer, giving it the AbstractBufWriter interface.
The BufWriter has an infinitely growable buffer, and will only expand the buffer if grow_buffer is called on it while it does not contain any data (as shown by get_unflushed).
Throw an ArgumentError if buffer_size is < 1.
julia> io = IOBuffer(); wtr = BufWriter(io);
julia> print(wtr, "Hello!")
julia> write(wtr, [0x1234, 0x5678])
4
julia> isempty(read(io)) # wtr not flushed
true
julia> flush(wtr); seekstart(io); String(read(io))
"Hello!4\x12xV"
julia> isempty(get_unflushed(wtr))
trueBufferIO.ByteVector — Type
ByteVector <: DenseVector{UInt8}A re-implementation of Vector{UInt8} that only supports a subset of its methods. In future minor releases, this may change to be an alias of Vector{UInt8}.
Note that String(x::ByteVector) will truncate x, to mirror the behaviour of String(::Vector{UInt8}). It is recommended to use takestring! instead.
All Base methods implemented for ByteVector is guaranteed to have the same semantics as those for Vector. Futhermore, ByteVector supports:
takestring!(::ByteVector)even on Julia < 1.13, whereastakestring!(::Vector{UInt8})is only defined from Julia 1.13 onwards.
BufferIO.CursorReader — Type
CursorReader(x) <: AbstractBufReaderA seekable, stateful reader of the content of any object x which implements MemoryView(x)::MemoryView{UInt8}.
Closing it does nothing.
julia> rdr = CursorReader("some\ncontent\nhere");
julia> readline(rdr)
"some"
julia> read(rdr, String)
"content\nhere"
julia> seek(rdr, 8);
julia> read(rdr, String)
"tent\nhere"BufferIO.IOError — Type
IOErrorThis type is thrown by errors of AbstractBufReader and AbstractBufWriter. They contain the .kind::IOErrorKind public property.
See also: IOErrorKinds.IOErrorKind
Examples
julia> rdr = CursorReader("some content");
julia> try
seek(rdr, 500)
catch error
if error.kind == IOErrorKinds.BadSeek
println(stderr, "Seeking operation out of bounds")
else
rethrow()
end
end
Seeking operation out of boundsBufferIO.IOReader — Type
IOReader{T <: AbstractBufReader} <: IOWrapper type to convert an AbstractBufReader to an IO.
IOReaders implement the same part of the IO interface as AbstractBufReader, so this type is only used to satisfy type constraints.
Examples
julia> io = CursorReader("hello");
julia> f(x::IO) = String(read(x));
julia> f(io)
ERROR: MethodError: no method matching f(::CursorReader)
[...]
julia> f(IOReader(io))
"hello"BufferIO.IOWriter — Type
IOWriter{T <: AbstractBufWriter} <: IOWrapper type to convert an AbstractBufWriter to an IO.
IOWriters implement the same part of the IO interface as AbstractBufWriter, so this type is only used to satisfy type constraints.
Examples
julia> io = VecWriter();
julia> f(x::IO) = write(x, "hello");
julia> f(io)
ERROR: MethodError: no method matching f(::VecWriter)
[...]
julia> f(IOWriter(io))
5
julia> String(io.vec)
"hello"BufferIO.LineViewIterator — Type
LineViewIterator{T <: AbstractBufReader}This iterator is created by line_views(::AbstractBufReader). It is public, but is currently unexported.
It has two public properties: io.reader obtains its inner AbstractBufReader, and io.chomp::Bool returns whether this iterator strips line endings.
For semantics of iteration, see documentation of line_views(::AbstractBufReader).
BufferIO.VecWriter — Type
VecWriter <: AbstractBufWriterA writer backed by a ByteVector. Read the (public) property .vec to get the vector back.
This type is useful as an efficient string builder through takestring!(io).
Functions flush and close do not affect the writer.
Mutating io will mutate vec and vice versa. Neither vec nor io will be invalidated by mutating the other, but doing so may affect the implicit (non-semantic) behaviour (e.g. memory reallocations or efficiency) of the other. For example, repeated and interleaved push!(vec) and write(io, x) may be less efficient, if one operation has memory allocation patterns that is suboptimal for the other operation.
Create with one of the following constructors:
VecWriter([vec::Vector{UInt8}])VecWriter(undef, ::Int)VecWriter(::ByteVector)
Note that, currently, when constructing from a Vector{UInt8}, the vector is invalidated and the VecWriter and its wrapped ByteVector take shared control of the underlying memory. This restriction may be lifted in the future.
A VecWriter has no notion of filesize, and cannot be seeked. Instead, resize the underlying vector io.vec.
julia> vw = VecWriter();
julia> write(vw, "Hello, world!", 0xe1fa)
15
julia> append!(vw.vec, b"More data");
julia> String(vw.vec)
"Hello, world!\xfa\xe1More data"BufferIO.consume — Function
consume(io::Union{AbstractBufReader, AbstractBufWriter}, n::Int)::NothingRemove the first n bytes of the buffer of io. Consumed bytes will not be returned by future calls to get_buffer.
If n is negative, or larger than the current buffer size, throw an IOError with ConsumeBufferError kind. This check is a boundscheck and may be elided with @inbounds.
Examples
julia> reader = CursorReader("abcdefghij");
julia> get_buffer(reader) == b"abcdefghij"
true
julia> consume(reader, 8); get_buffer(reader) |> println
UInt8[0x69, 0x6a]
julia> consume(reader, 3) # 2 bytes remaining
ERROR: Called `consume` with a negative amount, or larger than available buffer sizeBufferIO.fill_buffer — Function
fill_buffer(io::AbstractBufReader)::Union{Int, Nothing}Fill more bytes into the buffer from io's underlying buffer, returning the number of bytes added. After calling fill_buffer and getting n, the buffer obtained by get_buffer should have n new bytes appended.
This function must fill at least one byte, except
- If the underlying io is EOF, or there is no underlying io to fill bytes from, return 0
- If the buffer is not empty, and cannot be expanded, return
nothing.
Buffered readers which do not wrap another underlying IO, and therefore can't fill its buffer should return 0 unconditionally. This function should never return nothing if the buffer is empty.
Idiomatically, users should not call fill_buffer when the buffer is not empty, because doing so may force growing the buffer instead of letting io choose an optimal buffer size. Calling fill_buffer with a nonempty buffer is only appropriate if, for algorithmic reasons you need io itself to buffer some minimum amount of data.
Examples
julia> reader = CursorReader("abcde");
julia> fill_buffer(reader) # CursorReader can't fill its buffer
0
julia> reader = BufReader(IOBuffer("abcde"), 3);
julia> length(get_buffer(reader)) # buffer of BufReader initially empty
0
julia> fill_buffer(reader)
3
julia> length(get_buffer(reader)) # now must be 0 + 3
3BufferIO.get_buffer — Method
get_buffer(io::AbstractBufReader)::ImmutableMemoryView{UInt8}Get the available bytes of io.
Calling this function, even when the buffer is empty, should never do actual system I/O, and in particular should not attempt to fill the buffer. To fill the buffer, call fill_buffer.
Examples
julia> reader = BufReader(IOBuffer("abcdefghij"), 5);
julia> get_buffer(reader) |> isempty
true
julia> fill_buffer(reader)
5
julia> get_buffer(reader) |> println
UInt8[0x61, 0x62, 0x63, 0x64, 0x65]BufferIO.get_buffer — Method
get_buffer(io::AbstractBufWriter)::MutableMemoryView{UInt8}Get the available mutable buffer of io that can be written to.
Calling this function should never do actual system I/O, and in particular should not attempt to flush data from the buffer or grow the buffer. To increase the size of the buffer, call grow_buffer.
Examples
julia> writer = BufWriter(IOBuffer(), 5);
julia> buffer = get_buffer(writer);
julia> (typeof(buffer), length(buffer))
(MutableMemoryView{UInt8}, 5)
julia> write(writer, "abcde")
5
julia> get_buffer(writer) |> isempty
true
julia> flush(writer)
julia> buffer = get_buffer(writer); length(buffer)
5BufferIO.get_nonempty_buffer — Method
get_nonempty_buffer(x::AbstractBufReader)::Union{Nothing, ImmutableMemoryView{UInt8}}Get a buffer with at least one byte, if bytes are available. Otherwise, fill the buffer, and return the newly filled buffer. Returns nothing only if x is EOF.
Examples
julia> reader = BufReader(IOBuffer("abc"));
julia> get_buffer(reader) |> isempty
true
julia> get_nonempty_buffer(reader) |> println
UInt8[0x61, 0x62, 0x63]
julia> consume(reader, 3)
julia> get_nonempty_buffer(reader) === nothing # EOF
trueBufferIO.get_nonempty_buffer — Method
get_nonempty_buffer(x::AbstractBufWriter)::Union{Nothing, MutableMemoryView{UInt8}}Get a buffer with at least one byte, if bytes are available. Otherwise, call grow_buffer, then get the buffer again. Returns nothing if the buffer is still empty.
BufferIO.get_nonempty_buffer — Method
get_nonempty_buffer(
io::AbstractBufWriter, min_size::Int
)::Union{Nothing, MutableMemoryView{UInt8}}Get a buffer of at least size max(min_size, 1), or nothing if that is not possible.
This method is optionally implemented for subtypes of AbstractBufWriter, and is typically only implemented for types which do not flush their data to an underlying IO, such that there is no memory savings by writing in smaller chunks.
Use of this method may cause excessive buffering without flushing, which is less memory efficient than calling the one-argument method and flushing in a loop.
Examples
julia> function write_int_le(writer::AbstractBufWriter, int::Int64)
buf = get_nonempty_buffer(writer, sizeof(Int64))::Union{Nothing, MutableMemoryView{UInt8}}
isnothing(buf) && throw(IOError(IOErrorKinds.BufferTooShort))
length(buf) < sizeof(Int64) && error("Bad implementation of get_nonempty_buffer")
GC.@preserve buf unsafe_store!(Ptr{Int64}(pointer(buf)), htol(int))
@inbounds consume(writer, sizeof(Int64))
return sizeof(Int64)
end;
julia> v = VecWriter(); write_int_le(v, Int64(515))
8
julia> String(v.vec)
"\x03\x02\0\0\0\0\0\0"BufferIO.get_unflushed — Method
get_unflushed(io::AbstractBufWriter)::MutableMemoryView{UInt8}Return a view into the buffered data already written to io and consumed, but not yet flushed to its underlying IO.
Bytes not appearing in the buffer may not be completely flushed if there are more layers of buffering in the IO wrapped by io. However, any bytes already consumed and not returned in get_unflushed should not be buffered in io itself.
Mutating the returned buffer is allowed, and should not cause io to malfunction. After mutating the returned buffer and calling flush, values in the updated buffer will be flushed.
This function has no default implementation and methods are optionally added to subtypes of AbstractBufWriter that can fullfil the above restrictions.
Examples
julia> io = IOBuffer(); writer = BufWriter(io);
julia> isempty(get_unflushed(writer))
true
julia> write(writer, "abc"); unflushed = get_unflushed(writer);
julia> println(unflushed)
UInt8[0x61, 0x62, 0x63]
julia> unflushed[2] = UInt8('x')
0x78
julia> flush(writer); take!(io) |> println
UInt8[0x61, 0x78, 0x63]
julia> get_unflushed(writer) |> isempty
trueBufferIO.grow_buffer — Method
grow_buffer(io::AbstractBufWriter)::IntIncrease the amount of bytes in the writeable buffer of io if possible, returning the number of bytes added. After calling grow_buffer and getting n, the buffer obtained by get_buffer should have n more bytes.
The buffer is usually grown by flushing the buffer, expanding or reallocating the buffer. If none of these can grow the buffer, return zero.
Idiomatically, users should not call grow_buffer when the buffer is not empty, because doing so forces growing the buffer instead of letting io choose an optimal buffer size. Calling grow_buffer with a nonempty buffer is only appropriate if, for algorithmic reasons you need io buffer to be able to hold some minimum amount of data before flushing.
Examples
julia> v = VecWriter(undef, 0); get_buffer(v) |> isempty
true
julia> n_grown = grow_buffer(v); n_grown > 0
true
julia> length(get_buffer(v)) == n_grown
trueBufferIO.line_views — Method
line_views(x::AbstractBufReader; chomp::Bool=true)::LineViewIterator{typeof(x)}Create an iterator of lines of x. The returned views are ImmutableMemoryView{UInt8} into x's buffer. Use the package StringViews.jl to turn the lines into AbstractStrings.
The views may be invalidated when mutating x, which may happen on subsequent iterations of the iterator. See extended help for more precise semantics.
The chomp keyword (default: true), controls whether any trailing \r\n or \n bytes should be removed from the output.
Examples
julia> lines = line_views(CursorReader("abc\r\ndef\n\r\ngh"));
julia> first(lines) |> String
"abc"
julia> first(lines) == b"abc"
true
julia> first(iterate(lines, 9)) |> String
""
julia> sum(length, lines)
2
julia> isempty(lines)
trueExtended help
A line is defined as all data up to and including \n (0x0a) or \r\n (0x0d 0x0a), or the remainder of the data in io if no \n byte was found. If the input is empty, this iterator is also empty.
If x had a limited buffer size, and cannot grow its buffer, and an entire line cannot be kept in the buffer, an ArgumentError is thrown.
The resulting iterator will NOT close x when exhausted, this must be handled elsewhere.
Iterator state and io advancement
The resulting iterator itr::LineViewIterator's state is guaranteed, public interface:
iterate(itr)is equivalent toiterate(itr, 0)iterate(itr, n::Int)is equivalent toconsume(x, n); iterate(itr)- The state returned by
iterateis anIntequal to the length of the line emitted, plus the number of stripped\r\nor\nbytes, ifchomp.
These semantics together mean that a normal for-loop will exhaust the underlying io, and that no emitted line will be invalidated before the next call to iterate.
As an example, to read two lines, one may do:
# Read first line, and do something with it
(line_1, s) = iterate(itr); x = process(line_1)
# Two argument iterate advances itr to the begining of next line.
(line_2, s) = iterate(itr, s); y = process(line_2)
# Advance iterator from second line to third line
consume(itr.reader, s) # .reader is a public propertyBufferIO.line_views — Method
line_views(x::MemoryView{UInt8}; chomp::Bool=true)Return a stateless iterator of the lines in x. The returned views are ImmutableMemoryView{UInt8} views into x. Use the package StringViews.jl to turn them into AbstractStrings.
A line is defined as all data up to and including \n (0x0a) or \r\n (0x0d 0x0a), or the remainder of the data in io if no \n byte was found. If the input is empty, this iterator is also empty.
The chomp keyword (default: true), controls whether any trailing \r\n or \n should be removed from the output.
Examples
julia> mem = MemoryView("abc\r\ndef\nab\n");
julia> foreach(i -> println(repr(String(i))), line_views(mem))
"abc"
"def"
"ab"BufferIO.read_all! — Method
read_all!(io::AbstractBufReader, dst::MutableMemoryView{UInt8})::IntRead bytes into dst until either dst is filled or io is EOF, returning the number of bytes read.
Examples
julia> reader = BufReader(IOBuffer("abcdefgh"), 3);
julia> v = zeros(UInt8, 10);
julia> read_all!(reader, MemoryView(v))
8
julia> String(v)
"abcdefgh\0\0"BufferIO.read_into! — Method
read_into!(x::AbstractBufReader, dst::MutableMemoryView{UInt8})::IntRead bytes into the beginning of dst, returning the number of bytes read. This function will always read at least 1 byte, except when dst is empty, or x is EOF.
This function is defined generically for AbstractBufReader. New methods should strive to do at most one read call to the underlying IO, if x wraps such an IO.
Examples
julia> reader = CursorReader("abcde");
julia> v = zeros(UInt8, 8);
julia> read_into!(reader, MemoryView(v))
5
julia> println(v)
UInt8[0x61, 0x62, 0x63, 0x64, 0x65, 0x00, 0x00, 0x00]BufferIO.relative_seek — Method
relative_seek(io::AbstractBufReader, delta::Int) -> ioSeek the stream by delta relative to the current position. Seeking by a positive delta will advance the stream, and a negative delta rewinds the stream. When delta is zero, the stream is unchanged.
Seeking beyond either end of the stream will throw an IOError of kind BadSeek.
This method can be faster than seek, because it does not require io to query its absolute position, and therefore, in certain circumstances, the seeking can occur purely in-memory without interacting with the underlying IO.
BufferIO.resize_buffer — Method
resize_buffer(io::Union{BufWriter, BufReader}, n::Int) -> ioResize the internal buffer of io to exactly n bytes.
Throw an ArgumentError if n is less than 1, or lower than the currently number of buffered bytes (length of get_unflushed for BufWriter, length of get_buffer for BufReader).
julia> w = BufWriter(IOBuffer());
julia> write(w, "abc")
3
julia> length(get_buffer(resize_buffer(w, 5)))
2
julia> resize_buffer(w, 2)
ERROR: ArgumentError: Buffer size smaller than current number of buffered bytes
[...]
julia> shallow_flush(w)
3
julia> resize_buffer(w, 2) === w
trueBufferIO.shallow_flush — Method
shallow_flush(io::AbstractBufWriter)::IntClear the buffer(s) of io by writing to the underlying I/O, but do not flush the underlying I/O. Return the number of bytes flushed.
This function is not generically defined for AbstractBufWriter.
julia> io = IOBuffer();
julia> wtr = BufWriter(io);
julia> write(wtr, "hello!");
julia> take!(io)
UInt8[]
julia> shallow_flush(wtr)
6
julia> String(take!(io))
"hello!"BufferIO.skip_exact — Method
skip_exact(io::AbstractBufReader, n::Integer)::NothingLike skip, but throw an IOError of kind IOErrorKinds.EOF if n bytes could not be skipped.
See also: Base.skip
Examples
julia> reader = CursorReader("abcdefghij");
julia> position(reader)
0
julia> skip_exact(reader, 3)
julia> read(reader, 2) |> String
"de"
julia> skip_exact(reader, 6) # 5 bytes remaining
ERROR: End of fileBufferIO.write_repeated — Method
write_repeated(io::AbstractBufWriter, byte::UInt8, n::Integer)::IntWrite byte to io n times, or until io is full, and return the number of written bytes. This is equivalent to write(io, fill(byte, n)), but more efficient.
Throw an InexactError if n is negative.
Examples
julia> w = VecWriter(collect(b"abc"));
julia> write_repeated(w, UInt8('x'), 6)
6
julia> takestring!(w)
"abcxxxxxx"BufferIO.IOErrorKinds.IOErrorKind — Type
IOErrorKindEnum indicating what error was thrown. The current list is non-exhaustive, and more may be added in future releases. The integral value of these enums are subject to change in minor versions.
Current errors:
ConsumeBufferError: Occurs when callingconsumewith a negative amount of bytes, or with more bytes thanlength(get_buffer(io))EOF: Occurs when trying a reading operation on a file that has reached end-of-fileBufferTooShort: Thrown by various functions that require a minimum buffer size, which theiocannot provide. This should only be thrown if the buffer is unable to grow to the required size, and not if e.g. the buffer does not expand because the io is EOF.BadSeek: An out-of-bounds seek operation was attemptedPermissionDenied: Acces was denied to a system (filesystem, network, OS, etc.) resourceNotFound: Resource was not found, e.g. no such file or directoryBrokenPipe: The operation failed because a pipe was broken. This typically happens when writing to stdout or stderr, which then gets closed.AlreadyExists: Resource (e.g. file) could not be created because it already existsNotADirectory: Resource is unexpectedly not a directory. E.g. a path contained a non-directory file as an intermediate component.IsADirectory: Resource is a directory when a non-directory was expectedDirectoryNotEmpty: Operation cannot succeed because it requires an empty directoryInvalidFileName: File name was invalid for platform, e.g. too long name, or invalid characters.ClosedIO: Indicates an operation was done on a closed IO.
BufferIO.IOErrorKinds — Module
module IOErrorKindsUsed as a namespace for IOErrorKind.
Base.unsafe_read — Method
unsafe_read(io::AbstractBufReader, ref, nbytes::UInt)::Int
unsafe_read(io::AbstractBufReader, p::Ptr{UInt8}, nbytes::UInt)::IntCopy nbytes from io into ref, returning the number of bytes copied. If io reached end of file, stop at EOF. ref is converted to a pointer using cref = Base.cconvert(Ptr, ref), then Base.unsafe_convert(Ptr{UInt8}, cref).
Safety: The user must ensure that
- The resulting pointer is valid, and points to at least
nbytesof writeable memory. GC.@preserveingcrefpinsrefin memory, i.e. the pointer will not become invalid during theGC.@preserveblock.
Base.readavailable — Method
readavailable(io::AbstractBufReader)::Vector{UInt8}Read the available bytes of io to a new Vector{UInt8}, except if zero bytes are available. In that case, it will attempt to get more bytes exactly once. If still no bytes are available, io is EOF, and the resulting vector is empty.
Base.peek — Method
peek(io::AbstractBufReader)::UInt8Get the next UInt8 in io, without advancing io, or throw an IOError containing IOErrorKinds.EOF if io is EOF.
Base.read — Method
read(io::AbstractBufReader, UInt8)::UInt8Get the next UInt8 in io, or throw an IOError containing IOErrorKinds.EOF if io is EOF.
Base.readbytes! — Function
readbytes!(io::AbstractBufReader, b::AbstractVector{UInt8}, nb::Integer=length(b))::IntRead at most nb bytes from io into b, returning the number of bytes read. This function will read zero bytes if and only if io is EOF.
b must use one-based indexing. The size of b will be increased if needed (i.e. if nb is greater than length(b) and enough bytes could be read), but it will never be decreased.
It is generally preferred to use read_into! instead of this method.
Base.copyline — Method
copyline(
out::Union{IO, AbstractBufWriter},
from::AbstractBufReader;
keep::Bool = false
) -> outCopy one line from from to out, returning out. A line is defined as data up to and including \n (byte 0x0a), or all remaining data in from if no such byte is present.
If keep is false, as it is by default, the trailing \r\n (encoded as 0x0d 0x0a) or \n will not be copied to out, but it will be consumed from from.
This function may throw an IOerror with IOErrorKinds.BufferTooShort, if all the following occurs:
keepisfalse- The reader has a buffer size of 1
- The reader cannot expand its buffer
- The only byte in the buffer is
\r(0x0d).
Base.filesize — Method
filesize(io::AbstractBufReader)::IntGet the total size, in bytes, which can be read by io, and the span in which io can be seeked. Types implementing filesize should also implement seek.
The filesize does not depend on the current reading state of the io, i.e. reading bytes should not change the filesize.
Base.filesize — Method
filesize(io::AbstractBufWriter)::IntGet the filesize of io, in bytes.
The filesize is understood as the number of bytes flushed to the underlying resource of io, and which can be retrived by re-reading the data (so e.g. some streams like devnull may have a filesize of zero, even if many bytes was flushed to it.) The filesize does not depend on, and does not include, the number of buffered and unflushed bytes.
Types implementing filesize should also implement seek and position.
Base.seek — Method
seek(io::AbstractBufReader, offset::Int) -> ioSeek io to the zero-based position offset, if io supports seeking, and return io. When offset === 0, this is equivalent to seekstart. If filesize(io) is implemented, seek(io, filesize(io)) is equivalent to seekend(io).
Valid offsets are 0:filesize(io), if io implements filesize. Seeking outside these bounds throws an IOError of kind BadSeek.
This method is not generically defined for AbstractBufReader.
julia> rdr = BufReader(IOBuffer("Hello, world!"));
julia> String(read(rdr, 5))
"Hello"
julia> seek(rdr, 3);
julia> String(read(rdr, 5))
"lo, w"
julia> seek(rdr, 13);
julia> read(rdr)
UInt8[]Base.seek — Method
seek(io::AbstractBufWriter, offset::Int) -> ioFlush io, then seek io to the zero-based position offset.
Valid values for offset are in 0:filesize(io), if filesize(io) is defined. The filesize is computed after the flush. Seeking outside these bounds throws an IOError of kind BadSeek. Seeking should only change the filesize through its flush, so seeking an already-flushed stream should not change the filesize.
If seeking to before the current position (as defined by position), data between the new and the previous position need not be changed, and the underlying file or IO need not immediately be truncated. However, new write operations should write (or overwrite) data at the new position.
This method is not generically defined for AbstractBufWriter. Implementors of seek should also define filesize(io) and position(io)
Base.position — Method
Base.position(io::AbstractBufWriter)::IntGet the zero-based stream position.
If the stream position is p (zero-based), then the next byte written will be byte number p + 1 (one-based) in the file. The stream position does account for buffered (consumed, but unflushed) bytes, and therefore may exceed filesize. After calling flush, position must be in 0:filesize(io), if filesize is defined.
Base.position — Method
Base.position(io::AbstractBufReader)::IntGet the zero-based stream position.
If the stream position is p (zero-based), then the next byte read will be byte number p + 1 (one-based). The value of position must be in 0:filesize(io), if filesize is defined.
Examples
julia> reader = CursorReader("abcdefghij");
julia> position(reader) # zero-indexed
0
julia> read(reader, 3) |> String
"abc"
julia> position(reader)
3
julia> read(reader, 2) |> String
"de"
julia> position(reader)
5
julia> seekstart(reader); position(reader)
0Base.skip — Method
skip(io::AbstractBufReader, n::Integer)::IntRead n bytes from io, or until EOF, whichever comes first, and discard the read bytes. Return the number of bytes read.
This function is defined generically for AbstractBufReader by reading bytes, not by seeking. Subtypes of AbstractBufReader may implement this using seeking. In order to skip a generic AbstractBufReader and guarantee seeking is used, use seek(io, position(io) + n).
Throws an ArgumentError if n < 0.
See also: skip_exact
Examples
julia> reader = CursorReader("abcdefghij");
julia> skip(reader, 5)
5
julia> read(reader, 3) |> String
"fgh"
julia> skip(reader, 10) # 2 bytes remaining
2
julia> eof(reader)
true
julia> skip(reader, 100)
0