# Forcing bytes downward in Okio

DevFeed: [Forcing bytes downward in Okio](<https://devfeed.tech/articles/forcing-bytes-downward-in-okio-20937.md>)

Original publisher: [Read original article](<https://jakewharton.com/forcing-bytes-downward-in-okio/>)

Published: 2016-09-06T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Library](<https://devfeed.tech/topics/library.md>), [Streams](<https://devfeed.tech/topics/streams.md>), [IO](<https://devfeed.tech/topics/io.md>), [Java](<https://devfeed.tech/topics/java.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [io](<https://devfeed.tech/tags/io.md>), [java](<https://devfeed.tech/tags/java.md>), [jdk](<https://devfeed.tech/tags/jdk.md>), [library](<https://devfeed.tech/tags/library.md>), [nio](<https://devfeed.tech/tags/nio.md>), [performance](<https://devfeed.tech/tags/performance.md>), [streams](<https://devfeed.tech/tags/streams.md>)

## AI overview

This article explains how Okio moves buffered bytes through its sink chain. It compares flush(), emitCompleteSegments(), and close-related behavior, emphasizing their differences, buffering costs, and effects on correctness and throughput.

## Source excerpt

Okio's BufferedSink is a high-level abstraction for writing binary and character data as bytes. Its design stems from frustrations with the JDK's java.io.* and java.nio.* libraries. At Droidcon Montreal last year I gave a presentation comparing it with the former, but also showcased Okio's concept of a segment and how it enables the library to cheaply move bytes. If you aren't familiar with Okio I encourage you to go watch the presentation first since the rest of this post will assume at least cursory knowledge of its types. If you never look at the source code of Okio you won't know that this segment concept exists. It's an implementation detail for performance that remains completely opaque to the consumer of the library. That is, except for one* notable exception: the emitCompleteSegments() method on BufferedSink. This method is part of a family of three methods which force buffered bytes to be moved to the underlying Sink. Their difference is subtle, but understanding that difference ensures correctness and can make or break throughput. First let's understand the difference in behavior and then look at some use cases for each. flush() Flush is a common concept in stream APIs and its semantics remain unchanged in Okio. Calls to this method cause all buffered bytes to be moved to the underlying Sink and then that Sink is also instructed to flush itself. When calls to flush() return, you are guaranteed that all bytes have been sent all the way to the destination Sink. When multiple levels of buffering are in use, a call to flush() will clear the buffers at every level. In Okio multiple levels of buffering are so cheap that it's practically free. A flush just amounts to each level moving its segments down to the next level of the chain. With java.io.* streams, however, multiple levels of buffering require each level to allocate and manage its own byte[]. This means that a flush operation will result in each level doing an arraycopy() of its data down to the next lev