A modern I/O library for Android, Java, and Kotlin Multiplatform
npx @tessl/cli install tessl/maven-com-squareup-okio--okio@3.12.00
# Okio
1
2
Okio is a modern I/O library for Android, Java, and Kotlin Multiplatform that complements `java.io` and `java.nio` to make accessing, storing, and processing data much easier. Originally developed as a component of OkHttp, it provides efficient buffered I/O operations, file system abstractions, and cross-platform compatibility.
3
4
## Package Information
5
6
- **Package Name**: okio
7
- **Package Type**: maven
8
- **Language**: Kotlin Multiplatform
9
- **Group ID**: com.squareup.okio
10
- **Artifact ID**: okio
11
- **Installation**: Add to your `build.gradle.kts` dependencies: `implementation("com.squareup.okio:okio:3.12.0")`
12
13
## Core Imports
14
15
```kotlin
16
import okio.*
17
// Or specific imports:
18
import okio.ByteString
19
import okio.Buffer
20
import okio.FileSystem
21
import okio.Path
22
```
23
24
## Basic Usage
25
26
```kotlin
27
import okio.*
28
29
// Working with byte strings
30
val data = "Hello, Okio!".encodeUtf8()
31
println(data.base64()) // SGVsbG8sIE9raW8h
32
println(data.sha256().hex()) // Hash as hex string
33
34
// Buffered I/O operations
35
val buffer = Buffer()
36
buffer.writeUtf8("Hello, ")
37
buffer.writeUtf8("world!")
38
println(buffer.readUtf8()) // Hello, world!
39
40
// File system operations
41
val path = "/tmp/example.txt".toPath()
42
FileSystem.SYSTEM.write(path) {
43
writeUtf8("File content here")
44
}
45
val content = FileSystem.SYSTEM.read(path) {
46
readUtf8()
47
}
48
```
49
50
## Architecture
51
52
Okio is built around several key abstractions:
53
54
- **ByteString**: Immutable sequences of bytes with encoding/hashing capabilities
55
- **Buffer**: Mutable byte collections implementing both source and sink interfaces
56
- **Source/Sink**: Streaming I/O abstractions for reading and writing data
57
- **FileSystem**: Cross-platform file system operations with Path abstraction
58
- **Timeout**: Configurable timeout policies for I/O operations
59
60
The library uses efficient internal segment-based buffering and provides both low-level streaming APIs and high-level convenience methods.
61
62
## Capabilities
63
64
### Core I/O Operations
65
66
Essential byte manipulation, buffered I/O, and streaming operations.
67
68
```kotlin { .api }
69
// ByteString - immutable byte sequences
70
expect open class ByteString : Comparable<ByteString> {
71
val size: Int
72
fun utf8(): String
73
fun base64(): String
74
fun base64Url(): String
75
fun hex(): String
76
fun md5(): ByteString
77
fun sha1(): ByteString
78
fun sha256(): ByteString
79
fun sha512(): ByteString
80
fun hmacSha1(key: ByteString): ByteString
81
fun hmacSha256(key: ByteString): ByteString
82
fun hmacSha512(key: ByteString): ByteString
83
fun toAsciiLowercase(): ByteString
84
fun toAsciiUppercase(): ByteString
85
fun substring(beginIndex: Int = 0, endIndex: Int = size): ByteString
86
fun toByteArray(): ByteArray
87
operator fun get(index: Int): Byte
88
fun startsWith(prefix: ByteString): Boolean
89
fun endsWith(suffix: ByteString): Boolean
90
fun indexOf(other: ByteString, fromIndex: Int = 0): Int
91
fun rangeEquals(offset: Int, other: ByteString, otherOffset: Int = 0, byteCount: Int): Boolean
92
companion object {
93
val EMPTY: ByteString
94
fun of(vararg data: Byte): ByteString
95
}
96
}
97
98
// Buffer - mutable byte collections
99
expect class Buffer : BufferedSource, BufferedSink {
100
var size: Long
101
fun copyTo(out: Buffer, offset: Long = 0L, byteCount: Long): Buffer
102
fun copyTo(out: Buffer, offset: Long = 0L): Buffer
103
fun completeSegmentByteCount(): Long
104
operator fun get(pos: Long): Byte
105
fun clear()
106
fun skip(byteCount: Long)
107
fun snapshot(): ByteString
108
fun snapshot(byteCount: Int): ByteString
109
fun copy(): Buffer
110
fun md5(): ByteString
111
fun sha1(): ByteString
112
fun sha256(): ByteString
113
fun sha512(): ByteString
114
fun hmacSha1(key: ByteString): ByteString
115
fun hmacSha256(key: ByteString): ByteString
116
fun hmacSha512(key: ByteString): ByteString
117
}
118
119
// BufferedSource - efficient reading interface
120
expect sealed interface BufferedSource : Source {
121
val buffer: Buffer
122
fun exhausted(): Boolean
123
fun require(byteCount: Long)
124
fun request(byteCount: Long): Boolean
125
fun readByte(): Byte
126
fun readShort(): Short
127
fun readShortLe(): Short
128
fun readInt(): Int
129
fun readIntLe(): Int
130
fun readLong(): Long
131
fun readLongLe(): Long
132
fun readDecimalLong(): Long
133
fun readHexadecimalUnsignedLong(): Long
134
fun readUtf8(): String
135
fun readUtf8(byteCount: Long): String
136
fun readUtf8Line(): String?
137
fun readUtf8LineStrict(): String
138
fun readUtf8CodePoint(): Int
139
fun readByteString(): ByteString
140
fun readByteString(byteCount: Long): ByteString
141
fun readByteArray(): ByteArray
142
fun readByteArray(byteCount: Long): ByteArray
143
fun read(sink: ByteArray): Int
144
fun readFully(sink: ByteArray)
145
fun readFully(sink: Buffer, byteCount: Long)
146
fun readAll(sink: Sink): Long
147
fun skip(byteCount: Long)
148
fun indexOf(b: Byte): Long
149
fun indexOf(bytes: ByteString): Long
150
fun indexOfElement(targetBytes: ByteString): Long
151
fun rangeEquals(offset: Long, bytes: ByteString): Boolean
152
fun peek(): BufferedSource
153
fun select(options: Options): Int
154
fun <T : Any> select(options: TypedOptions<T>): T?
155
}
156
157
// BufferedSink - efficient writing interface
158
expect sealed interface BufferedSink : Sink {
159
val buffer: Buffer
160
fun write(byteString: ByteString): BufferedSink
161
fun write(byteString: ByteString, offset: Int, byteCount: Int): BufferedSink
162
fun write(source: ByteArray): BufferedSink
163
fun write(source: ByteArray, offset: Int, byteCount: Int): BufferedSink
164
fun writeAll(source: Source): Long
165
fun write(source: Source, byteCount: Long): BufferedSink
166
fun writeUtf8(string: String): BufferedSink
167
fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): BufferedSink
168
fun writeUtf8CodePoint(codePoint: Int): BufferedSink
169
fun writeByte(b: Int): BufferedSink
170
fun writeShort(s: Int): BufferedSink
171
fun writeShortLe(s: Int): BufferedSink
172
fun writeInt(i: Int): BufferedSink
173
fun writeIntLe(i: Int): BufferedSink
174
fun writeLong(v: Long): BufferedSink
175
fun writeLongLe(v: Long): BufferedSink
176
fun writeDecimalLong(v: Long): BufferedSink
177
fun writeHexadecimalUnsignedLong(v: Long): BufferedSink
178
override fun flush()
179
fun emit(): BufferedSink
180
fun emitCompleteSegments(): BufferedSink
181
}
182
```
183
184
```kotlin { .api }
185
// String extensions for ByteString creation
186
fun String.encodeUtf8(): ByteString
187
fun String.decodeBase64(): ByteString?
188
fun String.decodeHex(): ByteString
189
190
// ByteArray extensions
191
fun ByteArray.toByteString(offset: Int = 0, byteCount: Int = size): ByteString
192
193
// Source/Sink buffering utilities
194
fun Source.buffer(): BufferedSource
195
fun Sink.buffer(): BufferedSink
196
fun blackholeSink(): Sink
197
198
// Resource management
199
inline fun <T : Closeable?, R> T.use(block: (T) -> R): R
200
```
201
202
[Core I/O Operations](./core-io.md)
203
204
### File System Operations
205
206
Cross-platform file system access with path manipulation and metadata handling.
207
208
```kotlin { .api }
209
// Path - hierarchical file system addresses
210
expect class Path {
211
val root: Path?
212
val segments: List<String>
213
val isAbsolute: Boolean
214
val isRelative: Boolean
215
val volumeLetter: Char?
216
val name: String
217
val parent: Path?
218
val isRoot: Boolean
219
operator fun div(child: String): Path
220
operator fun div(child: ByteString): Path
221
operator fun div(child: Path): Path
222
fun resolve(child: String, normalize: Boolean = false): Path
223
fun resolve(child: ByteString, normalize: Boolean = false): Path
224
fun resolve(child: Path, normalize: Boolean = false): Path
225
fun relativeTo(other: Path): Path
226
fun normalized(): Path
227
companion object {
228
val DIRECTORY_SEPARATOR: String
229
}
230
}
231
232
// FileSystem - file and directory operations
233
expect abstract class FileSystem {
234
abstract fun canonicalize(path: Path): Path
235
fun metadata(path: Path): FileMetadata
236
abstract fun metadataOrNull(path: Path): FileMetadata?
237
fun exists(path: Path): Boolean
238
abstract fun list(dir: Path): List<Path>
239
abstract fun listOrNull(dir: Path): List<Path>?
240
open fun listRecursively(dir: Path, followSymlinks: Boolean = false): Sequence<Path>
241
abstract fun openReadOnly(file: Path): FileHandle
242
abstract fun openReadWrite(file: Path, mustCreate: Boolean = false, mustExist: Boolean = false): FileHandle
243
abstract fun source(file: Path): Source
244
inline fun <T> read(file: Path, readerAction: BufferedSource.() -> T): T
245
abstract fun sink(file: Path, mustCreate: Boolean = false): Sink
246
inline fun <T> write(file: Path, mustCreate: Boolean = false, writerAction: BufferedSink.() -> T): T
247
abstract fun appendingSink(file: Path, mustExist: Boolean = false): Sink
248
abstract fun createDirectory(dir: Path, mustCreate: Boolean = false)
249
fun createDirectories(dir: Path, mustCreate: Boolean = false)
250
abstract fun atomicMove(source: Path, target: Path)
251
open fun copy(source: Path, target: Path)
252
abstract fun delete(path: Path, mustExist: Boolean = false)
253
open fun deleteRecursively(fileOrDirectory: Path, mustExist: Boolean = false)
254
abstract fun createSymlink(source: Path, target: Path)
255
companion object {
256
val SYSTEM: FileSystem
257
val SYSTEM_TEMPORARY_DIRECTORY: Path
258
}
259
}
260
261
// FileHandle - random access file I/O
262
abstract class FileHandle : Closeable {
263
val readWrite: Boolean
264
fun read(fileOffset: Long, array: ByteArray, arrayOffset: Int = 0, byteCount: Int = array.size): Int
265
fun read(fileOffset: Long, sink: Buffer, byteCount: Long): Long
266
fun write(fileOffset: Long, array: ByteArray, arrayOffset: Int = 0, byteCount: Int = array.size)
267
fun write(fileOffset: Long, source: Buffer, byteCount: Long)
268
fun size(): Long
269
fun resize(size: Long)
270
fun flush()
271
fun source(fileOffset: Long = 0L): Source
272
fun sink(fileOffset: Long = 0L): Sink
273
fun appendingSink(): Sink
274
fun position(source: Source): Long
275
fun reposition(source: Source, position: Long)
276
fun position(sink: Sink): Long
277
fun reposition(sink: Sink, position: Long)
278
override fun close()
279
}
280
```
281
282
```kotlin { .api }
283
// String to Path conversion
284
fun String.toPath(normalize: Boolean = false): Path
285
286
// FileSystem convenience extensions
287
inline fun <T> FileSystem.read(file: Path, readerAction: BufferedSource.() -> T): T
288
inline fun <T> FileSystem.write(file: Path, mustCreate: Boolean = false, writerAction: BufferedSink.() -> T): T
289
290
// UTF-8 utilities
291
fun String.utf8Size(beginIndex: Int = 0, endIndex: Int = length): Long
292
```
293
294
[File System Operations](./filesystem.md)
295
296
### Compression and Encoding
297
298
Data compression using GZIP and deflate algorithms with native zlib integration.
299
300
```kotlin { .api }
301
// GZIP compression
302
class GzipSink(sink: Sink) : Sink {
303
val deflater: Deflater
304
}
305
fun Sink.gzip(): GzipSink
306
307
// Deflate compression (native implementation)
308
actual class Deflater {
309
constructor()
310
constructor(level: Int, nowrap: Boolean)
311
var flush: Int
312
fun getBytesRead(): Long
313
fun end()
314
}
315
316
// ZIP file system access
317
class ZipFileSystem(zipPath: Path, fileSystem: FileSystem) : FileSystem
318
```
319
320
[Compression and Encoding](./compression.md)
321
322
### Hashing and Security
323
324
Cryptographic hashing operations and secure data handling.
325
326
```kotlin { .api }
327
// Hashing sources and sinks
328
expect class HashingSource(source: Source, digest: Digest) : Source {
329
val hash: ByteString
330
}
331
332
expect class HashingSink(sink: Sink, digest: Digest) : Sink {
333
val hash: ByteString
334
}
335
```
336
337
Built-in hash functions available on ByteString and Buffer:
338
- MD5: `md5(): ByteString`
339
- SHA-1: `sha1(): ByteString`
340
- SHA-256: `sha256(): ByteString`
341
- SHA-512: `sha512(): ByteString`
342
- HMAC variants: `hmacSha1()`, `hmacSha256()`, `hmacSha512()`
343
344
[Hashing and Security](./hashing.md)
345
346
### Utilities and Extensions
347
348
Helper functions, timeout management, and advanced buffer operations.
349
350
```kotlin { .api }
351
// Timeout management
352
expect open class Timeout {
353
companion object {
354
val NONE: Timeout
355
}
356
}
357
358
// Selection and matching
359
class Options private constructor() : List<ByteString> {
360
companion object {
361
fun of(vararg byteStrings: ByteString): Options
362
}
363
}
364
365
class TypedOptions<T : Any> private constructor() : List<T> {
366
companion object {
367
inline fun <T : Any> of(values: Iterable<T>, encode: (T) -> ByteString): TypedOptions<T>
368
}
369
}
370
```
371
372
```kotlin { .api }
373
// BufferedSource selection operations
374
fun BufferedSource.select(options: Options): Int
375
fun <T : Any> BufferedSource.select(options: TypedOptions<T>): T?
376
377
// Advanced buffer operations (UnsafeCursor for high-performance access)
378
class Buffer.UnsafeCursor {
379
var buffer: Buffer?
380
var readWrite: Boolean
381
var offset: Long
382
var data: ByteArray?
383
var start: Int
384
var end: Int
385
fun next(): Int
386
fun seek(offset: Long): Int
387
}
388
```
389
390
[Utilities and Extensions](./utilities.md)
391
392
## Platform-Specific Features
393
394
### Apple Platform Extensions
395
396
Additional functionality specific to Apple platforms:
397
398
```kotlin { .api }
399
// Foundation integration
400
fun NSData.toByteString(): ByteString
401
```
402
403
### Native Platform Features
404
405
- **Native zlib integration**: High-performance compression using system libraries
406
- **POSIX file system**: Optimized file operations for Unix-like systems
407
- **Memory-mapped I/O**: Efficient file access patterns
408
- **Platform-specific optimizations**: ARM64-optimized implementations
409
410
## Error Handling
411
412
Okio uses standard Kotlin/platform exception types:
413
414
```kotlin { .api }
415
expect open class IOException : Exception
416
expect class FileNotFoundException : IOException
417
expect class EOFException : IOException
418
expect class ProtocolException : IOException
419
```
420
421
Common error scenarios:
422
- **FileNotFoundException**: When accessing non-existent files
423
- **EOFException**: When reading past end of stream
424
- **IOException**: For general I/O failures
425
- **IllegalArgumentException**: For invalid parameters
426
427
## Threading and Concurrency
428
429
- **Thread-safe**: ByteString instances are immutable and thread-safe
430
- **Buffer synchronization**: Buffer operations require external synchronization for concurrent access
431
- **FileSystem operations**: Platform-dependent thread safety (SYSTEM instance is generally thread-safe)
432
- **Timeout support**: All I/O operations support configurable timeouts
433
434
## Types
435
436
```kotlin { .api }
437
// Core interfaces
438
interface Source : Closeable {
439
fun read(sink: Buffer, byteCount: Long): Long
440
fun timeout(): Timeout
441
}
442
443
interface Sink : Closeable {
444
fun write(source: Buffer, byteCount: Long)
445
fun flush()
446
fun timeout(): Timeout
447
}
448
449
interface Closeable {
450
fun close()
451
}
452
453
// File metadata
454
class FileMetadata(
455
val isRegularFile: Boolean = false,
456
val isDirectory: Boolean = false,
457
val symlinkTarget: Path? = null,
458
val size: Long? = null,
459
val createdAtMillis: Long? = null,
460
val lastModifiedAtMillis: Long? = null,
461
val lastAccessedAtMillis: Long? = null,
462
val extras: Map<KClass<*>, Any> = emptyMap()
463
)
464
465
// Platform synchronization
466
expect class Lock() {
467
inline fun <T> withLock(action: () -> T): T
468
}
469
```