What it is
Okio is a library for I/O in Kotlin and Java, offering buffered sources and sinks, a multiplatform filesystem abstraction and efficient byte handling.
Source reads, Sink writes, and Buffer holds bytes efficiently. FileSystem provides a testable, multiplatform filesystem API.
Installation
implementation("com.squareup.okio:okio:3.9.0")Getting started
The smallest useful thing you can do with it, and what each part means.
kotlin
val path = "books.json".toPath()
FileSystem.SYSTEM.write(path) {
writeUtf8(json)
}
val text = FileSystem.SYSTEM.read(path) {
readUtf8()
}
// Streaming line by line — constant memory on a huge file.
FileSystem.SYSTEM.source(path).buffer().use { source ->
while (true) {
val line = source.readUtf8Line() ?: break
process(line)
}
}Advanced usage
Where the library earns its place over a simpler alternative.
kotlin
// A real FileSystem implementation with no disk — tests run fast
// and cannot leave files behind.
val fs = FakeFileSystem()
fs.write("config.json".toPath()) { writeUtf8("""{"port":8080}""") }
val service = ConfigService(fs) // inject the filesystem
assertEquals(8080, service.load().port)
fs.checkNoOpenFiles() // asserts nothing leaked
// Hash while streaming, without buffering the whole file.
val sha = FileSystem.SYSTEM.source(path).buffer().use { it.readByteString().sha256() }
// ByteString is immutable and cheap to compare and encode.
val token = "secret".encodeUtf8().sha256().hex()Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- FileNotFoundException on a path that exists
- Okio paths are platform-aware. Build them with toPath() and resolve() rather than concatenating strings.
- Data is missing after writing
- The sink was not closed or flushed. Use the write { } lambda, which handles both.
Best practices
- Inject FileSystem rather than using java.io directly, so tests can substitute FakeFileSystem.
- Use .buffer() on sources and sinks; unbuffered I/O is much slower.
- Use ByteString for immutable byte data — it is safe to share and cheap to compare.
- Call checkNoOpenFiles() in tests to catch leaked handles.
Background
Why it exists, and what it was reacting to.
Built by Square as OkHttp's foundation, Okio exists because java.io's streams are awkward and allocate heavily. Its ByteString and Buffer types move data with far less copying.
