# \[ANN\] TruncatedStreams.jl - Streams that lie about EOF

**URL:** <https://discourse.julialang.org/t/ann-truncatedstreams-jl-streams-that-lie-about-eof/118197>\
**Category:** Package Announcements\
**Tags:** package, announcement, io\
**Created:** [August 14, 2024, 7:16pm UTC](https://discourse.julialang.org/t/ann-truncatedstreams-jl-streams-that-lie-about-eof/118197 "2024-08-14T19:16:07Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![reallyasi9](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/reallyasi9/32/207648_2.png) [@reallyasi9](https://discourse.julialang.org/u/reallyasi9)\
**Post date:** [August 14, 2024, 7:16pm UTC](https://discourse.julialang.org/t/ann-truncatedstreams-jl-streams-that-lie-about-eof/118197/1 "2024-08-14T19:16:07Z")

</div>

## Synopsis

[`TruncatedStreams.jl`](https://github.com/reallyasi9/TruncatedStreams.jl) provides types that meet the following four criteria:

1. Inherit from `Base.IO`;
2. Transparently pass all basic IO methods through to a wrapped `IO` object, except…
3. Lie about `eof` and…
4. Do not read a single byte more from the wrapped `IO` object than what is necessary to determine EOF.

```julia
using TruncatedStreams

io = IOBuffer(collect(0x00:0xff))

fixed_io = FixedLengthIO(io, 10) # pretend EOF occurs after the first 10 bytes are read
@assert read(fixed_io) == collect(0x00:0x09)
@assert eof(fixed_io) == true
@assert eof(io) == false # a lie, but a useful one!
@assert peek(io) == 0x0a # read exactly 10 bytes from io and not a byte more

sentinel_io = SentinelIO(io, [0x10, 0x11]) # pretend EOF occurs as soon as the sentinel is read
@assert read(sentinel_io) == collect(0x0a:0x0f)
@assert eof(sentinel_io) == true
@assert eof(io) == false
@assert peek(io) == 0x12 # the sentinel is consumed, but not a byte more

close(io)

```
