or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compression.mdcore-io.mdfilesystem.mdhashing.mdindex.mdutilities.md

core-io.mddocs/

0

# Core I/O Operations

1

2

This document covers Okio's essential byte manipulation, buffered I/O, and streaming operations. These are the fundamental building blocks for all data processing in Okio.

3

4

## ByteString

5

6

ByteString represents an immutable sequence of bytes with built-in encoding, hashing, and comparison capabilities.

7

8

### Creation

9

10

```kotlin { .api }

11

// From companion object

12

val empty = ByteString.EMPTY

13

val fromBytes = ByteString.of(0x48, 0x65, 0x6c, 0x6c, 0x6f) // "Hello"

14

15

// From String extensions

16

val fromString = "Hello, Okio!".encodeUtf8()

17

18

// From ByteArray extensions

19

val bytes = byteArrayOf(0x48, 0x65, 0x6c, 0x6c, 0x6f)

20

val fromByteArray = bytes.toByteString()

21

val fromByteArrayRange = bytes.toByteString(offset = 1, byteCount = 3)

22

```

23

24

### Core Properties and Methods

25

26

```kotlin { .api }

27

expect open class ByteString internal constructor(data: ByteArray) : Comparable<ByteString> {

28

// Properties

29

val size: Int

30

operator fun get(index: Int): Byte

31

32

// Text conversion

33

fun utf8(): String

34

35

// Encoding

36

fun base64(): String

37

fun base64Url(): String

38

fun hex(): String

39

40

// Hashing

41

fun md5(): ByteString

42

fun sha1(): ByteString

43

fun sha256(): ByteString

44

fun sha512(): ByteString

45

fun hmacSha1(key: ByteString): ByteString

46

fun hmacSha256(key: ByteString): ByteString

47

fun hmacSha512(key: ByteString): ByteString

48

49

// Case conversion

50

fun toAsciiLowercase(): ByteString

51

fun toAsciiUppercase(): ByteString

52

53

// Manipulation

54

fun substring(beginIndex: Int = 0, endIndex: Int = size): ByteString

55

fun toByteArray(): ByteArray

56

fun copyInto(offset: Int = 0, target: ByteArray, targetOffset: Int = 0, byteCount: Int = minOf(size - offset, target.size - targetOffset)): Int

57

58

// Comparison and search

59

fun rangeEquals(offset: Int, other: ByteString, otherOffset: Int = 0, byteCount: Int): Boolean

60

fun startsWith(prefix: ByteString): Boolean

61

fun endsWith(suffix: ByteString): Boolean

62

fun indexOf(other: ByteString, fromIndex: Int = 0): Int

63

fun lastIndexOf(other: ByteString, fromIndex: Int = size): Int

64

65

// Comparison

66

override fun compareTo(other: ByteString): Int

67

override fun equals(other: Any?): Boolean

68

override fun hashCode(): Int

69

override fun toString(): String

70

71

companion object {

72

val EMPTY: ByteString

73

fun of(vararg data: Byte): ByteString

74

fun read(inputStream: InputStream, byteCount: Int): ByteString

75

}

76

}

77

```

78

79

### Extension Functions

80

81

```kotlin { .api }

82

// String to ByteString conversion

83

fun String.encodeUtf8(): ByteString

84

fun String.decodeBase64(): ByteString?

85

fun String.decodeHex(): ByteString

86

87

// ByteArray to ByteString conversion

88

fun ByteArray.toByteString(offset: Int = 0, byteCount: Int = size): ByteString

89

```

90

91

### Usage Examples

92

93

```kotlin

94

// Creating and manipulating ByteStrings

95

val data = "Hello, Okio!".encodeUtf8()

96

println("Size: ${data.size}") // Size: 12

97

println("Base64: ${data.base64()}") // Base64: SGVsbG8sIE9raW8h

98

println("Hex: ${data.hex()}") // Hex: 48656c6c6f2c204f6b696f21

99

100

// Hashing

101

val hash = data.sha256()

102

println("SHA-256: ${hash.hex()}")

103

104

// Substring operations

105

val hello = data.substring(0, 5) // "Hello"

106

val okio = data.substring(7, 11) // "Okio"

107

108

// Search operations

109

val commaIndex = data.indexOf(",".encodeUtf8()) // 5

110

val startsWithHello = data.startsWith("Hello".encodeUtf8()) // true

111

```

112

113

## Buffer

114

115

Buffer is a mutable collection of bytes that implements both BufferedSource and BufferedSink, providing efficient byte array pooling and segment-based storage.

116

117

### Core Buffer Operations

118

119

```kotlin { .api }

120

expect class Buffer() : BufferedSource, BufferedSink {

121

// Properties

122

var size: Long

123

override val buffer: Buffer // Returns self

124

125

// Basic operations

126

fun copyTo(out: Buffer, offset: Long = 0L, byteCount: Long): Buffer

127

fun copyTo(out: Buffer, offset: Long = 0L): Buffer // Overload for remaining bytes

128

fun completeSegmentByteCount(): Long

129

operator fun get(pos: Long): Byte

130

fun clear()

131

fun skip(byteCount: Long)

132

133

// Hashing (same as ByteString)

134

fun md5(): ByteString

135

fun sha1(): ByteString

136

fun sha256(): ByteString

137

fun sha512(): ByteString

138

fun hmacSha1(key: ByteString): ByteString

139

fun hmacSha256(key: ByteString): ByteString

140

fun hmacSha512(key: ByteString): ByteString

141

142

// Buffer management

143

fun copy(): Buffer

144

fun snapshot(): ByteString

145

fun snapshot(byteCount: Int): ByteString

146

147

// Advanced operations

148

fun readUnsafe(unsafeCursor: UnsafeCursor = UnsafeCursor()): UnsafeCursor

149

fun readAndWriteUnsafe(unsafeCursor: UnsafeCursor = UnsafeCursor()): UnsafeCursor

150

}

151

```

152

153

### UnsafeCursor for High-Performance Access

154

155

```kotlin { .api }

156

class Buffer.UnsafeCursor {

157

var buffer: Buffer?

158

var readWrite: Boolean

159

var offset: Long

160

var data: ByteArray?

161

var start: Int

162

var end: Int

163

164

fun next(): Int

165

fun seek(offset: Long): Int

166

fun resizeBuffer(newSize: Long): Long

167

fun expandBuffer(minByteCount: Int): Long

168

}

169

```

170

171

### Usage Examples

172

173

```kotlin

174

// Basic buffer operations

175

val buffer = Buffer()

176

buffer.writeUtf8("Hello")

177

buffer.writeUtf8(", ")

178

buffer.writeUtf8("Okio!")

179

180

println("Buffer size: ${buffer.size}") // 12

181

println("Content: ${buffer.readUtf8()}") // Hello, Okio!

182

183

// Copying data between buffers

184

val source = Buffer().writeUtf8("Source data")

185

val destination = Buffer()

186

source.copyTo(destination)

187

188

// Snapshot to immutable ByteString

189

val buffer2 = Buffer().writeUtf8("Test data")

190

val snapshot = buffer2.snapshot() // Creates ByteString without consuming buffer

191

```

192

193

## Source and Sink

194

195

Source and Sink are the fundamental streaming interfaces in Okio.

196

197

### Source Interface

198

199

```kotlin { .api }

200

interface Source : Closeable {

201

/**

202

* Removes at least 1, and up to byteCount bytes from this source and appends them to sink.

203

* Returns the number of bytes read, or -1 if this source is exhausted.

204

*/

205

fun read(sink: Buffer, byteCount: Long): Long

206

207

/**

208

* Returns the timeout for this source.

209

*/

210

fun timeout(): Timeout

211

212

/**

213

* Closes this source and releases the resources held by this source.

214

*/

215

override fun close()

216

}

217

```

218

219

### Sink Interface

220

221

```kotlin { .api }

222

expect interface Sink : Closeable {

223

/**

224

* Removes exactly byteCount bytes from source and appends them to this sink.

225

*/

226

fun write(source: Buffer, byteCount: Long)

227

228

/**

229

* Pushes all buffered bytes to their final destination.

230

*/

231

fun flush()

232

233

/**

234

* Returns the timeout for this sink.

235

*/

236

fun timeout(): Timeout

237

238

/**

239

* Closes this sink and releases the resources held by this sink.

240

*/

241

override fun close()

242

}

243

```

244

245

### Utility Functions

246

247

```kotlin { .api }

248

// Convert Source/Sink to buffered versions

249

fun Source.buffer(): BufferedSource

250

fun Sink.buffer(): BufferedSink

251

252

// Utility sinks

253

fun blackholeSink(): Sink

254

255

// Resource management

256

inline fun <T : Closeable?, R> T.use(block: (T) -> R): R

257

```

258

259

## BufferedSource

260

261

BufferedSource provides an efficient interface for reading data with internal buffering.

262

263

### Reading Primitives

264

265

```kotlin { .api }

266

expect sealed interface BufferedSource : Source {

267

// Buffer access

268

val buffer: Buffer

269

270

// State checking

271

fun exhausted(): Boolean

272

fun require(byteCount: Long) // Throws EOFException if not available

273

fun request(byteCount: Long): Boolean // Returns false if not available

274

275

// Byte reading

276

fun readByte(): Byte

277

fun readShort(): Short

278

fun readShortLe(): Short

279

fun readInt(): Int

280

fun readIntLe(): Int

281

fun readLong(): Long

282

fun readLongLe(): Long

283

284

// Number parsing

285

fun readDecimalLong(): Long

286

fun readHexadecimalUnsignedLong(): Long

287

288

// Skipping

289

fun skip(byteCount: Long)

290

291

// Bulk reading

292

fun readByteString(): ByteString

293

fun readByteString(byteCount: Long): ByteString

294

fun readByteArray(): ByteArray

295

fun readByteArray(byteCount: Long): ByteArray

296

297

// Array reading

298

fun read(sink: ByteArray): Int

299

fun read(sink: ByteArray, offset: Int, byteCount: Int): Int

300

fun readFully(sink: ByteArray)

301

fun readFully(sink: Buffer, byteCount: Long)

302

fun readAll(sink: Sink): Long

303

304

// String reading

305

fun readUtf8(): String

306

fun readUtf8(byteCount: Long): String

307

fun readUtf8Line(): String?

308

fun readUtf8LineStrict(): String

309

fun readUtf8LineStrict(limit: Long): String

310

fun readUtf8CodePoint(): Int

311

}

312

```

313

314

### Search and Selection Operations

315

316

```kotlin { .api }

317

expect sealed interface BufferedSource : Source {

318

// Selection

319

fun select(options: Options): Int

320

fun <T : Any> select(options: TypedOptions<T>): T?

321

322

// Search for bytes

323

fun indexOf(b: Byte): Long

324

fun indexOf(b: Byte, fromIndex: Long): Long

325

fun indexOf(b: Byte, fromIndex: Long, toIndex: Long): Long

326

327

// Search for byte strings

328

fun indexOf(bytes: ByteString): Long

329

fun indexOf(bytes: ByteString, fromIndex: Long): Long

330

fun indexOf(bytes: ByteString, fromIndex: Long, toIndex: Long): Long

331

332

// Search for any of multiple bytes

333

fun indexOfElement(targetBytes: ByteString): Long

334

fun indexOfElement(targetBytes: ByteString, fromIndex: Long): Long

335

336

// Range comparison

337

fun rangeEquals(offset: Long, bytes: ByteString): Boolean

338

fun rangeEquals(offset: Long, bytes: ByteString, bytesOffset: Int, byteCount: Int): Boolean

339

340

// Peek source (non-consuming reads)

341

fun peek(): BufferedSource

342

}

343

```

344

345

### Usage Examples

346

347

```kotlin

348

// Reading different data types

349

val source = Buffer()

350

.writeByte(42)

351

.writeInt(1234)

352

.writeUtf8("Hello")

353

354

val byte = source.readByte() // 42

355

val int = source.readInt() // 1234

356

val text = source.readUtf8() // "Hello"

357

358

// Line-based reading

359

val lines = Buffer().writeUtf8("Line 1\nLine 2\nLine 3\n")

360

while (!lines.exhausted()) {

361

val line = lines.readUtf8Line()

362

println("Read: $line")

363

}

364

365

// Selection-based reading

366

val options = Options.of("GET".encodeUtf8(), "POST".encodeUtf8(), "PUT".encodeUtf8())

367

val request = Buffer().writeUtf8("POST /api/users")

368

val method = request.select(options) // Returns 1 (index of "POST")

369

```

370

371

## BufferedSink

372

373

BufferedSink provides an efficient interface for writing data with internal buffering.

374

375

### Writing Operations

376

377

```kotlin { .api }

378

expect sealed interface BufferedSink : Sink {

379

// Buffer access

380

val buffer: Buffer

381

382

// ByteString and ByteArray writing

383

fun write(byteString: ByteString): BufferedSink

384

fun write(byteString: ByteString, offset: Int, byteCount: Int): BufferedSink

385

fun write(source: ByteArray): BufferedSink

386

fun write(source: ByteArray, offset: Int, byteCount: Int): BufferedSink

387

388

// Source writing

389

fun writeAll(source: Source): Long

390

fun write(source: Source, byteCount: Long): BufferedSink

391

392

// String writing

393

fun writeUtf8(string: String): BufferedSink

394

fun writeUtf8(string: String, beginIndex: Int, endIndex: Int): BufferedSink

395

fun writeUtf8CodePoint(codePoint: Int): BufferedSink

396

397

// Primitive writing

398

fun writeByte(b: Int): BufferedSink

399

fun writeShort(s: Int): BufferedSink

400

fun writeShortLe(s: Int): BufferedSink

401

fun writeInt(i: Int): BufferedSink

402

fun writeIntLe(i: Int): BufferedSink

403

fun writeLong(v: Long): BufferedSink

404

fun writeLongLe(v: Long): BufferedSink

405

406

// Number formatting

407

fun writeDecimalLong(v: Long): BufferedSink

408

fun writeHexadecimalUnsignedLong(v: Long): BufferedSink

409

410

// Buffer management

411

override fun flush()

412

fun emit(): BufferedSink

413

fun emitCompleteSegments(): BufferedSink

414

}

415

```

416

417

### Usage Examples

418

419

```kotlin

420

// Basic writing operations

421

val sink = Buffer()

422

sink.writeUtf8("Hello, ")

423

.writeUtf8("Okio!")

424

.writeByte(10) // newline

425

.writeInt(42)

426

.flush()

427

428

// Writing different data types

429

val data = Buffer()

430

data.writeByte(0xFF)

431

.writeShort(1234)

432

.writeInt(0x12345678)

433

.writeLong(System.currentTimeMillis())

434

.writeUtf8("Timestamp")

435

436

// Chaining operations

437

val output = Buffer()

438

.writeUtf8("HTTP/1.1 200 OK\r\n")

439

.writeUtf8("Content-Type: application/json\r\n")

440

.writeUtf8("Content-Length: 13\r\n")

441

.writeUtf8("\r\n")

442

.writeUtf8("{\"ok\": true}")

443

```

444

445

## Advanced Buffer Features

446

447

### Segment Pool Optimization

448

449

Okio uses internal segment pools to minimize memory allocations and garbage collection:

450

451

```kotlin

452

// Efficient data movement - segments are moved, not copied

453

val source = Buffer().writeUtf8("Large data chunk")

454

val destination = Buffer()

455

source.copyTo(destination) // Segments are transferred, not duplicated

456

```

457

458

### Memory-Efficient Operations

459

460

```kotlin

461

// Reading large files without loading everything into memory

462

val largeFile: Source = // ... source for large file

463

val processedData = Buffer()

464

465

largeFile.use { source ->

466

val buffered = source.buffer()

467

while (!buffered.exhausted()) {

468

val chunk = buffered.readByteString(8192) // Read 8KB chunks

469

val processed = processData(chunk)

470

processedData.write(processed)

471

}

472

}

473

```

474

475

## Error Handling

476

477

Common exceptions when working with core I/O operations:

478

479

```kotlin { .api }

480

expect open class IOException : Exception

481

expect class EOFException : IOException

482

expect class ArrayIndexOutOfBoundsException : Exception

483

```

484

485

- **EOFException**: Thrown when trying to read beyond available data

486

- **ArrayIndexOutOfBoundsException**: Thrown for invalid array access

487

- **IOException**: General I/O operation failures