:wave: I'm looking for a way to know the source's ...
# io
f
👋 I'm looking for a way to know the source's length, without consuming it until the end. I would like to skip but with some control before
✅ 1
f
Hey! In general, there's no way to figure out source's length without consuming the source until exhaustion. Assuming you're sure that the source has some limited length, what could work is transferring all data from the source into a buffer and then checking its length:
Copy code
val source: Source = ...
val buffer = Buffer()
source.transferTo(buffer) // that will consume the source
println(buffer.size)
👀 1
f
Stupid question: how does the C# do? I find C# stream more convenient than the JVM [Input|Ouput]Stream 😅
f
how does the C# do?
By providing an interface whose implementations would, in general, throw
NotSupportedException
on an attempt to get the length 🙂 Not every source can have a length. It's easy to find it for in-memory buffers and regular files, but for sources like network streams there's not such a property. The intended way of transforming incoming data in kotlinx-io is by wrapping one source into another. Once it's done, even if the underlying source was a file, it's no longer possible to guess the length. As an example, consider reading a gzipped file. To do so, one may open a file source and wrap it into gzip-decoding-source. The file source definitely has a length (assuming that's a regular file), but there's no way to find decompressed data length until it's read in full. C# folks decided to throw an exception when the length could not be retrieved, for Okio and kotlinx-io the decision was to abstain from providing such a property. If you're working with files, the length could be checked by calling
FileSystem::metadaOrNull(path)?.size
[kdoc]. And for in memory sources, a.k.a. Buffers, the size property is already there.
f
Thanks for the explanations. I was simply thinking that the size was always available, somehow in headers or something like this 😅