1Change Log 2========== 3 4## Version 3.10.2 5 6_2025-01-08_ 7 8 * Fix: `okio-nodefilesystem` artifact is no longer empty. 9 10 11## Version 3.10.1 12 13_2025-01-07_ 14 15 * New: `FileSystem.close()` may prevent future access and/or clean up associated resources depending on the backing implementation. `FakeFileSystem` will prevent future operations once closed. 16 * `InputStream`s created from `BufferedSource.inputStream()` now have a more efficient version of `InputStream.transferTo()` which reduces memory copies. 17 * `okio-nodefilesystem` is no longer publised as a JS project, but a Kotlin multiplatform project with only a JS target. ~This change should not affect consumers in any way, and is motivated by the Kotlin Gradle plugin deprecating the JS-only plugin.~ Please use 3.10.2 to ensure this change actually does not affect your builds. 18 19 20## Version 3.10.0 21 22_2025-01-06_ 23 24This version is equivalent to the subsequent 3.10.1, but it did not fully publish to Maven Central due to infrastructure problems. 25 26 27## Version 3.9.1 28 29_2024-09-12_ 30 31 * Fix: Support paths containing a single dot (".") in `Path.relativeTo`. 32 * Fix: Do not read from the upstream source when a 0-byte read is requested. 33 * Fix: Update kotlinx.datetime to 0.6.0 to correct a Gradle module metadata problem with 0.5.0. 34 Note: this artifact is only used in 'okio-fakefilesystem' and 'okio-nodefilesystem' and not in the Okio core. 35 36 37## Version 3.9.0 38 39_2024-03-12_ 40 41 * New: `FileSystem.SYSTEM` can be used in source sets that target both Kotlin/Native and 42 Kotlin/JVM. Previously, we had this symbol in each source set but it wasn't available to 43 common source sets. 44 * New: `COpaquePointer.readByteString(...)` creates a ByteString from a memory address. 45 * New: Support `InflaterSource`, `DeflaterSink`, `GzipSink`, and `GzipSource` in Kotlin/Native. 46 * New: Support openZip() on Kotlin/Native. One known bug in this implementation is that 47 `FileMetadata.lastModifiedAtMillis()` is interpreted as UTC and not the host machine's time zone. 48 * New: Prefer NTFS timestamps in ZIP file systems' metadata. This avoids the time zone problems 49 of ZIP's built-in DOS timestamps, and the 2038 time bombs of ZIP's extended timestamps. 50 * Fix: Don't leak file handles to opened JAR files open in `FileSystem.RESOURCES`. 51 * Fix: Don't throw a `NullPointerException` if `Closeable.use { ... }` returns null. 52 53 54## Version 3.8.0 55 56_2024-02-09_ 57 58 * New: `TypedOptions` works like `Options`, but it returns a `T` rather than an index. 59 * Fix: Don't leave sinks open when there's a race in `Pipe.fold()`. 60 61 62## Version 3.7.0 63 64_2023-12-16_ 65 66 * New: `Timeout.cancel()` prevents a timeout from firing. 67 * Breaking: Drop the `watchosX86` Kotlin/Native target. From [the Kotlin blog][watchosX86], 68 _‘This is an obsolete simulator for Intel Macs. Use the watchosX64 target instead.’_ 69 * New: Add the `watchosDeviceArm64` Kotlin/Native target. 70 * New: `Timeout` APIs that accept `kotlin.time.Duration`. 71 * Upgrade: [Kotlin 1.9.21][kotlin_1_9_21]. 72 73 74## Version 3.6.0 75 76_2023-10-01_ 77 78 * Fix: Don't leak file handles when using `metadata` functions on `ZipFileSystem`. We had a bug 79 where we were closing the `.zip` file, but not a stream inside of it. We would have prevented 80 this bug if only we’d used `FakeFileSystem.checkNoOpenFiles()` in our tests! 81 * Fix: Don't build an index of a class loader's resources in `ResourceFileSystem.read()`. This 82 operation doesn't need this index, and building it is potentially expensive. 83 * New: Experimentally support Linux on ARM64 for Kotlin/Native targets (`linuxArm64`). Note that 84 we haven't yet added CI test coverage for this platform. 85 * Upgrade: [Kotlin 1.9.10][kotlin_1_9_10]. 86 87 88## Version 1.17.6 89 90_2023-10-01_ 91 92 * Fix: Don't crash decoding GZIP files when the optional extra data (`XLEN`) is 32 KiB or larger. 93 94 95## Version 3.5.0 96 97_2023-08-02_ 98 99 * New: Support the WebAssembly (WASM) platform. Okio's support for WASM is experimental, but 100 improving, just like Kotlin's own support for WASM. 101 * New: Adapt WebAssembly System Interface (WASI) API's as an Okio FileSystem using 102 `WasiFileSystem`. This is in the new `okio-wasifilesystem` module. It requires the [preview1] 103 WASI API. We’ll make backwards-incompatible upgrades to new WASI API versions as they become 104 available. 105 * Fix: Return relative paths in the NIO adapter FileSystem when required. `FileSystem.list()` 106 had always returned absolute paths, even when the target directory was supplied as a relative 107 path. 108 * Fix: Don't crash when reading into an empty array using `FileHandle` on Kotlin/Native. 109 * Upgrade: [Kotlin 1.9.0][kotlin_1_9_0]. 110 111 112## Version 3.4.0 113 114_2023-07-07_ 115 116 * New: Adapt a Java NIO FileSystem (`java.nio.file.FileSystem`) as an Okio FileSystem using 117 `fileSystem.asOkioFileSystem()`. 118 * New: Adapt Android’s `AssetManager` as an Okio FileSystem using `AssetFileSystem`. This is in the 119 new `okio-assetfilesystem` module. Android applications should prefer this over 120 `FileSystem.RESOURCES` as it’s faster to load. 121 * Fix: Don't crash decoding GZIP files when the optional extra data (`XLEN`) is 32 KiB or larger. 122 * Fix: Resolve symlinks in `FakeFileSystem.canonicalize()`. 123 * Fix: Report the correct `createdAtMillis` in `NodeJsFileSystem` file metadata. We were 124 incorrectly using `ctimeMs`, where `c` means _changed_, not _created_. 125 * Fix: `UnsafeCursor` is now `Closeable`. 126 127 128## Version 3.3.0 129 130_2023-01-07_ 131 132 * Fix: Don't leak resources when `use {}` is used with a non-local return. We introduced this 133 performance and stability bug by not considering that non-local returns execute neither the 134 `return` nor `catch` control flows. 135 * Fix: Use a sealed interface for `BufferedSink` and `BufferedSource`. These were never intended 136 for end-users to implement, and we're happy that Kotlin now allows us to express that in our API. 137 * New: Change internal locks from `synchronized` to `ReentrantLock` and `Condition`. We expect this 138 to improve help when using Okio with Java virtual threads ([Project Loom][loom]). 139 * Upgrade: [Kotlin 1.8.0][kotlin_1_8_0]. 140 141 142## Version 3.2.0 143 144_2022-06-26_ 145 146 * Fix: Configure the multiplatform artifact (`com.squareup.okio:okio:3.x.x`) to depend on the 147 JVM artifact (`com.squareup.okio:okio-jvm:3.x.x`) for Maven builds. This should work-around an 148 issue where Maven doesn't interpret Gradle metadata. 149 * Fix: Change `CipherSource` and `CipherSink` to recover if the cipher doesn't support streaming. 150 This should work around a crash with AES/GCM ciphers on Android. 151 * New: Enable compatibility with non-hierarchical projects. 152 153 154## Version 3.1.0 155 156_2022-04-19_ 157 158 * Upgrade: [Kotlin 1.6.20][kotlin_1_6_20]. 159 * New: Support [Hierarchical project structure][hierarchical_projects]. If you're using Okio in a 160 multiplatform project please upgrade your project to Kotlin 1.6.20 (or newer) to take advantage 161 of this. With hierarchical projects it's easier to use properties like `FileSystem.SYSTEM` that 162 are available on most Okio platforms but not all of them. 163 * New: `ForwardingSource` is now available on all platforms. 164 * New: The `watchosX64` platform is now supported. 165 * Fix: Don't crash in `NSData.toByteString()' when the input is empty. 166 * Fix: Support empty ZIP files in `FileSystem.openZip()`. 167 * Fix: Throw in `canonicalize()` of ZIP file systems if the path doesn't exist. 168 * Fix: Don't require ZIP files start with a local file header. 169 * New: `okio.ProtocolException` is a new exception type for multiplatform users. (It is aliased to 170 `java.net.ProtocolException` on JVM platforms). 171 172 173## Version 3.0.0 174 175_2021-10-28_ 176 177This is the first stable release of Okio 3.x. This release is strongly backwards-compatible with 178Okio 2.x, and the new major version signifies new capabilities more than it does backwards 179incompatibility. 180 181Most users should be able to upgrade from 2.x by just changing the version. If you're using Okio 182in a Kotlin Multiplatform project, you'll need to drop the `-multiplatform` suffix in your Gradle 183dependencies. 184 185 * New: Remove `@ExperimentalFileSystem`. This annotation is no longer necessary as the file system 186 is no longer experimental! 187 * New: Path no longer aggressively normalizes `..` segments. Use `Path.normalize()` to apply these 188 based on the content of the path, or `FileSystem.canonicalize()` to do it honoring any symlinks 189 on a particular file system. 190 * New: Publish a [bill of materials (BOM)][bom] for Okio. Depend on this from Gradle or Maven to 191 keep all of your Okio artifacts on the same version, even if they're declared via transitive 192 dependencies. You can even omit versions when declaring other Okio dependencies. 193 194 ```kotlin 195 dependencies { 196 api(platform("com.squareup.okio:okio-bom:3.0.0")) 197 api("com.squareup.okio:okio") // No version! 198 api("com.squareup.okio:okio-fakefilesystem") // No version! 199 } 200 ``` 201 202 * New: `FileSystem.delete()` silently succeeds when deleting a file that doesn't exist. Use 203 the new `mustExist` parameter to trigger an exception instead. 204 * New: `FileSystem.createDirectories()` silently succeeds when creating a directory that already 205 exists. Use the new `mustCreate` parameter to trigger an exception instead. 206 * New: `FileSystem` offers Java-language overloads where appropriate. Previously functions that 207 had default parameters were potentially awkward to invoke from Java. 208 * New: `Timeout.intersectWith()` returns a value instead of `Unit`. This is a binary-incompatible 209 change. We expect that this public API is very rarely used outside of Okio itself. 210 * Fix: Change `BufferedSource.readDecimalLong()` to fail if the input value is just `-`. Previously 211 Okio incorrectly returned `0` for this. 212 213 214## Version 3.0.0-alpha.11 215 216_2021-10-23_ 217 218 * Upgrade: [Kotlin 1.5.31][kotlin_1_5_31]. 219 * Upgrade: [kotlinx-datetime 0.3.0][datetime_0_3_0]. (This is a dependency of `okio-fakefilesystem` 220 only.) 221 * New: Support creating and accessing symlinks. We were reluctant to include symlinks in our API 222 (to keep it small!) but decided that supporting them was essential to properly implement 223 recursive traversal. 224 * New: `FileMetadata.extras` can track metadata for custom `FileSystem` implementations. 225 * New: Support Apple Silicon Kotlin/Native targets (`macosArm64`, `iosSimulatorArm64`, 226 `tvosSimulatorArm64`, and `watchosSimulatorArm64`). 227 * New: `FileSystem.listRecursively()` returns a `Sequence` that includes all of a directory's 228 children, and all of their children recursively. The implementation does a lazy, depth-first 229 traversal. 230 * New: `Path.relativeTo()` computes how to get from one path to another. 231 * New: `Path.root` and `Path.segments`. These APIs decompose a path into its component parts. 232 * New: `FileSystem.listOrNull()` returns a directory's children, or null if the path doesn't 233 reference a readable directory. 234 * New: Option to fail if the file being updated doesn't already exist: `mustExist`. Use this to 235 avoid creating a new file when your intention is to update an existing file. 236 * New: Option to fail if a file being created already exists: `mustCreate`. Use this to avoid 237 updating an existing file when your intention is to create a new file. 238 * Fix: Restore support for Kotlin/JS on browser platforms. We were relying on NodeJS-only features 239 to fetch the local directory separator (`/` or `\`) and temporary directory. 240 * Fix: Don't ignore the caller's specified write offset running Okio on Kotlin/Native on Linux. 241 (`FileHandle.write()` was broken and always appended to the end of the file.) 242 243 244## Version 3.0.0-alpha.10 245 246_2021-09-09_ 247 248This release drops the `-multiplatform` suffix on Kotlin Multiplatform artifacts. All artifacts now 249share the same name (like `com.squareup.okio:okio:3.0.0-alpha.10`) for both Kotlin/JVM and Kotlin 250Multiplatform. 251 252 * Fix: Don't crash in `ResourceFileSystem` when classpath `.jar` files have special characters in 253 their paths. 254 255 256## Version 3.0.0-alpha.9 257 258_2021-08-01_ 259 260 * New: `ByteString.copyInto()` saves an allocation when extracting data from a `ByteString`. 261 * Fix: Create `FileHandle.protectedSize()` to match other abstract functions. 262 * Fix: Open files in binary mode on Windows. Without this, files that contain `0x1a` will be 263 truncated prematurely. 264 265 266## Version 3.0.0-alpha.8 267 268_2021-07-13_ 269 270 * Fix: Don't crash on duplicate entries in a .zip file. 271 * Fix: Change `FileSystem.RESOURCES` to initialize itself lazily. 272 273 274## Version 3.0.0-alpha.7 275 276_2021-07-12_ 277 278 * Fix: Change `ResourceFileSystem` to load roots eagerly. We had a bug where `list()` on the root 279 returned an empty list even if resources were present. 280 * New: `FileHandle.reposition()` can seek on a source or sink returned by that `FileHandle`. 281 * New: Move the system resources instance to `FileSystem.RESOURCES`. 282 * Upgrade: [Kotlin 1.5.20][kotlin_1_5_20]. 283 284 285## Version 3.0.0-alpha.6 286 287_2021-06-01_ 288 289 * New: `FileHandle` supports random access reads, writes, and resizes on files. Create an instance 290 with `FileSystem.openReadOnly()` or `FileSystem.openReadWrite()`. 291 * New: Remove `Cursor` which is obsoleted by `FileHandle`. (`UnsafeCursor` is still around!) 292 * New: Add support for the new intermediate representation (IR) artifacts in Kotlin/JS. We still 293 support the legacy artifact format. 294 * New: Support tvOS (tvosArm64, tvosX64) in multiplatform. 295 * New: Change `ResourceFileSystem` to omit `.class` files when indexing `.zip` files. We expect 296 this to lower the memory footprint of `ResourceFileSystem`. 297 * Fix: Don't crash on background thread access in Kotlin/Native. We had to apply `@SharedImmutable` 298 and run our test suite on a background thread. 299 300 301## Version 3.0.0-alpha.5 302 303_2021-04-27_ 304 305 * New: Promote the `ZipFileSystem` and `ResourceFileSystem` to the main Okio module. These are 306 currently JVM-only. The `okio-zipfilesystem` module is no longer published. 307 308 309## Version 3.0.0-alpha.4 310 311_2021-04-14_ 312 313 * Fix: Rename internal classes to avoid name collisions. We were seeing problems due to having 314 multiple files named `-Platform.kt`. 315 316 317## Version 3.0.0-alpha.3 318 319_2021-04-06_ 320 321 * New: Move `NodeJsFileSystem` into its own module. Having it built-in prevented Okio from working 322 in a browser where there's no synchronous file system API. This is in the `okio-nodefilesystem` 323 artifact. 324 325 326## Version 3.0.0-alpha.2 327 328_2021-03-24_ 329 330 * New: Require Java 8+ for Okio 3.x. 331 * New: `Cursor` supports random access reads on a `Source`. 332 * New: `FileSystem.openZip(path)` returns a file system backed by a `.zip` file. This is in the 333 `okio-zipfilesystem` artifact. 334 335 336## Version 3.0.0-alpha.1 337 338_2021-01-07_ 339 340* New: Experimental file system API. The `Path`, `FileMetadata`, `FileSystem` and 341 `ForwardingFileSystem` types are subject to API changes in a future release. 342* New: Experimental `okio-fakefilesystem` artifact. 343 344 345## Version 2.10.0 346 347_2021-01-07_ 348 349* New: Support Windows (mingwX64) in multiplatform. 350* New: Support watchOS (watchosArm32, watchosArm64, watchosX86) in multiplatform. 351* New: Support `HashingSource`, `HashingSink`, buffer hash functions, and `UnsafeCursor` on non-JVM 352 platforms. Previously these were all JVM-only. 353* New: Implement `Closeable` on `Sink` and `Source` on non-JVM platforms. Okio now includes a 354 multiplatform `okio.Closeable` interface and corresponding `use {}` extension. Closing resources 355 when you're done with them shouldn't be JVM-only! 356* New: `Sink.hashingSink` and `Source.hashingSource` functions that accept 357 `java.security.MessageDigest` and `javax.crypto.Mac` instances. Use these when your hash function 358 isn't built-in. 359* Fix: Don't crash with a `ShortBufferException` in `CipherSink` and `CipherSource` on Android. 360 (Android may throw a `ShortBufferException` even if the buffer is not too short. We now 361 avoid this problem!) 362* Upgrade: [Kotlin 1.4.20][kotlin_1_4_20]. 363 364 365## Version 2.9.0 366 367_2020-10-04_ 368 369 * Fix: Don't corrupt the `Buffer` when writing a slice of a segmented `ByteString`. We had a severe 370 bug where `ByteString` instances created with `snapshot()` and `readByteString()` incorrectly 371 adjusted the buffer's size by their full length, not the length of the slice. This would have 372 caused buffer reads to crash! We do not believe data was silently corrupted. 373 * New: `CipherSink` and `CipherSource`. Use these with `javax.crypto.Cipher` to encrypt and decrypt 374 streams of data. This is a low-level encryption API; most applications should use higher-level 375 APIs like TLS when available. 376 * New: Promote hash functions `md5`, `sha1()`, `sha512()`, and `sha256()` to common Kotlin. These 377 are currently only available on `ByteString`, multiplatform support for `HashingSource`, 378 `HashingSink`, and `Buffer` should come in a follow-up release. We wrote and optimized our own 379 implementations of these hash functions in Kotlin. On JVM and Android platforms Okio still uses 380 the platform's built-in hash functions. 381 * New: Support OSGi metadata. 382 * Upgrade: [Kotlin 1.4.10][kotlin_1_4_10]. 383 384 385## Version 2.8.0 386 387_2020-08-17_ 388 389 * New: Upgrade to Kotlin 1.4.0. 390 391 392## Version 2.7.0 393 394_2020-07-07_ 395 396 * New: `Pipe.cancel()` causes in-progress and future reads and writes on the pipe to immediately 397 fail with an `IOException`. The streams may still be canceled normally. 398 399 * New: Enlarge Okio's internal segment pool from a fixed 64 KiB total to 64 KiB per processor. For 400 example, on an Intel i9 8-core/16-thread machine the segment pool now uses up to 1 MiB of memory. 401 402 * New: Migrate from `synchronized` to lock-free when accessing the segment pool. Combined with the 403 change above we saw throughput increase 3x on a synthetic benchmark designed to create 404 contention. 405 406 407## Version 2.6.0 408 409_2020-04-22_ 410 411 * New: `InflaterSource.readOrInflate()` is like `InflaterSource.read()`, except it will return 0 if 412 consuming deflated bytes from the underlying stream did not produce new inflated bytes. 413 414 415## Version 2.5.0 416 417_2020-03-20_ 418 419 * New: Upgrade to Kotlin 1.3.70. 420 421 422## Version 2.4.3 423 424_2019-12-20_ 425 426 * New: Upgrade to Kotlin 1.3.61. 427 428 429## Version 2.4.2 430 431_2019-12-11_ 432 433 * Fix: Don't crash when an `InputStream` source is exhausted exactly at a buffer segment boundary. 434 We had a bug where a sequence of reads could violate a buffer's invariants, and this could result 435 in a crash when subsequent reads encountered an unexpected empty segment. 436 437 438## Version 1.17.5 439 440_2019-12-11_ 441 442 * Fix: Don't crash when an `InputStream` source is exhausted exactly at a buffer segment boundary. 443 We had a bug where a sequence of reads could violate a buffer's invariants, and this could result 444 in a crash when subsequent reads encountered an unexpected empty segment. 445 446 447## Version 2.4.1 448 449_2019-10-04_ 450 451 * Fix: Don't cache hash code and UTF-8 string in `ByteString` on Kotlin/Native which prevented freezing. 452 453## Version 2.4.0 454 455_2019-08-26_ 456 457 * New: Upgrade to Kotlin 1.3.50. 458 459 460## Version 2.3.0 461 462_2019-07-29_ 463 464**This release changes our build from Kotlin-JVM to Kotlin-multiplatform (which includes JVM).** 465Both native and JavaScript platforms are unstable preview releases and subject to 466backwards-incompatible changes in forthcoming releases. 467 468To try Okio in a multiplatform project use this Maven coordinate: 469 470```kotlin 471api('com.squareup.okio:okio-multiplatform:2.3.0') 472``` 473 474You’ll also need to [enable Gradle metadata][gradle_metadata] in your project's settings. The 475artifact name for JVM projects has not changed. 476 477 * New: Upgrade to Kotlin 1.3.40. 478 * Fix: Use Gradle `api` instead of `implementation` for the kotlin-stdlib dependency. 479 * Fix: Don't block unless strictly necessary in `BufferedSource.peek()`. 480 481## Version 1.17.4 482 483_2019-04-29_ 484 485 * Fix: Don't block unless strictly necessary in `BufferedSource.peek()`. 486 487 488## Version 2.2.2 489 490_2019-01-28_ 491 492 * Fix: Make `Pipe.fold()` close the underlying sink when necessary. 493 494 495## Version 1.17.3 496 497_2019-01-28_ 498 499 * Fix: Make `Pipe.fold()` close the underlying sink when necessary. 500 501 502## Version 1.17.2 503 504_2019-01-17_ 505 506 * Fix: Make `Pipe.fold()` flush the underlying sink. 507 508 509## Version 2.2.1 510 511_2019-01-17_ 512 513 * Fix: Make `Pipe.fold()` flush the underlying sink. 514 515 516## Version 2.2.0 517 518_2019-01-16_ 519 520 * New: `Throttler` limits sources and sinks to a maximum desired throughput. Multiple sources and 521 sinks can be attached to the same throttler and their combined throughput will not exceed the 522 desired throughput. Multiple throttlers can also be used on the same source or sink and they will 523 all be honored. 524 525 * New: `Pipe.fold()` replaces the actively-readable `Source` with a passively-writable `Sink`. 526 This can be used to forward one sink to a target that is initially undetermined. 527 528 * New: Optimize performance of ByteStrings created with `Buffer.snapshot()`. 529 530 531## Version 1.17.1 532 533_2019-01-16_ 534 535 * Fix: Make the newly-backported `Pipe.fold()` public. 536 537 538## Version 1.17.0 539 540_2019-01-16_ 541 542 * New: Backport `Pipe.fold()` to Okio 1.x. 543 544 545## Version 1.16.0 546 547_2018-10-08_ 548 549 * New: Backport `BufferedSource.peek()` and `BufferedSource.getBuffer()` to Okio 1.x. 550 * Fix: Enforce timeouts when closing `AsyncTimeout` sources. 551 552 553## Version 2.1.0 554 555_2018-09-22_ 556 557 * New: `BufferedSource.peek()` returns another `BufferedSource` that reads ahead on the current 558 source. Use this to process the same data multiple times. 559 560 * New: Deprecate `BufferedSource.buffer()`, replacing it with either `BufferedSource.getBuffer()` 561 (in Java) or `BufferedSource.buffer` (in Kotlin). We have done likewise for `BufferedSink`. 562 When we introduced the new extension method `Source.buffer()` in Okio 2.0 we inadvertently 563 collided with an existing method. This fixes that. 564 565 * New: Improve performance of `Buffer.writeUtf8()`. This comes alongside initial implementation of 566 UTF-8 encoding and decoding in JavaScript which [uses XOR masks][xor_utf8] for great performance. 567 568 569## Version 2.0.0 570 571_2018-08-27_ 572 573This release commits to a stable 2.0 API. Read the 2.0.0-RC1 changes for advice on upgrading from 5741.x to 2.x. 575 576We've also added APIs to ease migration for Kotlin users. They use Kotlin's `@Deprecated` annotation 577to help you change call sites from the 1.x style to the 2.x style. 578 579 580## Version 2.0.0-RC1 581 582_2018-07-26_ 583 584Okio 2 is a major release that upgrades the library's implementation language from Java to Kotlin. 585 586Okio 2.x is **binary-compatible** with Okio 1.x and does not change any behavior. Classes and .jar 587files compiled against 1.x can be used with 2.x without recompiling. 588 589Okio 2.x is **.java source compatible** with Okio 1.x in all but one corner case. In Okio 1.x 590`Buffer` would throw an unchecked `IllegalStateException` when attempting to read more bytes than 591available. Okio 2.x now throws a checked `EOFException` in this case. This is now consistent with 592the behavior of its `BufferedSource` interface. Java callers that don't already catch `IOException` 593will now need to. 594 595Okio 2.x is **.kt source-incompatible** with Okio 1.x. This release adopts Kotlin idioms where they 596are available. 597 598| Java | Kotlin | Idiom | 599| :--------------------------------------- | :---------------------------------- | :----------------- | 600| Buffer.getByte() | operator fun Buffer.get() | operator function | 601| Buffer.size() | val Buffer.size | val | 602| ByteString.decodeBase64(String) | fun String.decodeBase64() | extension function | 603| ByteString.decodeHex(String) | fun String.decodeHex() | extension function | 604| ByteString.encodeString(String, Charset) | fun String.encode(Charset) | extension function | 605| ByteString.encodeUtf8(String) | fun String.encodeUtf8() | extension function | 606| ByteString.getByte() | operator fun ByteString.get() | operator function | 607| ByteString.of(ByteBuffer) | fun ByteBuffer.toByteString() | extension function | 608| ByteString.of(byte[], int, int) | fun ByteArray.toByteString() | extension function | 609| ByteString.read(InputStream, int) | fun InputStream.readByteString(Int) | extension function | 610| ByteString.size() | val ByteString.size | val | 611| DeflaterSink(Sink) | fun Sink.deflater() | extension function | 612| ForwardingSink.delegate() | val ForwardingSink.delegate | val | 613| ForwardingSource.delegate() | val ForwardingSource.delegate | val | 614| GzipSink(Sink, Deflater) | fun Sink.gzip() | extension function | 615| GzipSink.deflater() | val GzipSink.deflater | val | 616| GzipSource(Source) | fun Source.gzip() | extension function | 617| HashingSink.hash() | val HashingSink.hash | val | 618| HashingSource.hash() | val HashingSource.hash | val | 619| InflaterSink(Source) | fun Source.inflater() | extension function | 620| Okio.appendingSink(File) | fun File.appendingSink() | extension function | 621| Okio.blackhole() | fun blackholeSink() | top level function | 622| Okio.buffer(Sink) | fun Sink.buffer() | extension function | 623| Okio.buffer(Source) | fun Source.buffer() | extension function | 624| Okio.sink(File) | fun File.sink() | extension function | 625| Okio.sink(OutputStream) | fun OutputStream.sink() | extension function | 626| Okio.sink(Path) | fun Path.sink() | extension function | 627| Okio.sink(Socket) | fun Socket.sink() | extension function | 628| Okio.source(File) | fun File.source() | extension function | 629| Okio.source(InputStream) | fun InputStream.source() | extension function | 630| Okio.source(Path) | fun Path.source() | extension function | 631| Okio.source(Socket) | fun Socket.source() | extension function | 632| Pipe.sink() | val Pipe.sink | val | 633| Pipe.source() | val Pipe.source | val | 634| Utf8.size(String) | fun String.utf8Size() | extension function | 635 636Okio 2.x has **similar performance** to Okio 1.x. We benchmarked both versions to find potential 637performance regressions. We found one regression and fixed it: we were using `==` instead of `===`. 638 639Other changes in this release: 640 641 * New: Add a dependency on kotlin-stdlib. Okio's transitive dependencies grow from none in 1.x to 642 three in 2.x. These are kotlin-stdlib (939 KiB), kotlin-stdlib-common (104 KiB), and JetBrains' 643 annotations (17 KiB). 644 645 * New: Change Okio to build with Gradle instead of Maven. 646 647 648## Version 1.15.0 649 650_2018-07-18_ 651 652 * New: Trie-based `Buffer.select()`. This improves performance when selecting 653 among large lists of options. 654 * Fix: Retain interrupted state when throwing `InterruptedIOException`. 655 656 657## Version 1.14.0 658 659_2018-02-11_ 660 661 * New: `Buffer.UnsafeCursor` provides direct access to Okio internals. This API 662 is like Okio's version of Java reflection: it's a very powerful API that can 663 be used for great things and dangerous things alike. The documentation is 664 extensive and anyone using it should review it carefully before proceeding! 665 * New: Change `BufferedSource` to implement `java.nio.ReadableByteChannel` and 666 `BufferedSink` to implement `java.nio.WritableByteChannel`. Now it's a little 667 easier to interop between Okio and NIO. 668 * New: Automatic module name of `okio` for use with the Java Platform Module 669 System. 670 * New: Optimize `Buffer.getByte()` to search backwards when doing so will be 671 more efficient. 672 * Fix: Honor the requested byte count in `InflaterSource`. Previously this 673 class could return more bytes than requested. 674 * Fix: Improve a performance bug in `AsyncTimeout.sink().write()`. 675 676 677## Version 1.13.0 678 679_2017-05-12_ 680 681 * **Okio now uses `@Nullable` to annotate all possibly-null values.** We've 682 added a compile-time dependency on the JSR 305 annotations. This is a 683 [provided][maven_provided] dependency and does not need to be included in 684 your build configuration, `.jar` file, or `.apk`. We use 685 `@ParametersAreNonnullByDefault` and all parameters and return types are 686 never null unless explicitly annotated `@Nullable`. 687 688 * **Warning: this release is source-incompatible for Kotlin users.** 689 Nullability was previously ambiguous and lenient but now the compiler will 690 enforce strict null checks. 691 692 693## Version 1.12.0 694 695_2017-04-11_ 696 697 * **Fix: Change Pipe's sink.flush() to not block.** Previously closing a pipe's 698 sink would block until the source had been exhausted. In practice this 699 blocked the caller for no benefit. 700 * **Fix: Change `writeUtf8CodePoint()` to emit `?` for partial surrogates.** 701 The previous behavior was inconsistent: given a malformed string with a 702 partial surrogate, `writeUtf8()` emitted `?` but `writeUtf8CodePoint()` threw 703 an `IllegalArgumentException`. Most applications will never encounter partial 704 surrogates, but for those that do this behavior was unexpected. 705 * New: Allow length of `readUtf8LineStrict()` to be limited. 706 * New: `Utf8.size()` method to get the number of bytes required to encode a 707 string as UTF-8. This may be useful for length-prefixed encodings. 708 * New: SHA-512 hash and HMAC APIs. 709 710 711## Version 1.11.0 712 713_2016-10-11_ 714 715 * **Fix: The four-argument overload of `Buffer.writeString()` had a major bug 716 where it didn't respect offsets if the specified charset was UTF-8.** This 717 was because our short-circuit optimization omitted necessary offset 718 parameters. 719 * New: HMAC support in `HashingSource`, `HashingSink`, `ByteString`, and 720 `Buffer`. This makes it easy to create a keyed-hash message authentication 721 code (HMAC) wherever your data is. Unlike the other hashes, HMAC uses a 722 `ByteString` secret key for authentication. 723 * New: `ByteString.of(ByteBuffer)` makes it easier to mix NIO with Okio. 724 725 726## Version 1.10.0 727 728_2016-08-28_ 729 730 * Fix: Support reading files larger than 2 GiB with `GzipSource`. Previously 731 attempting to decompress such files would fail due to an overflow when 732 validating the total length. 733 * Fix: Exit the watchdog thread after being idle for 60 seconds. This should 734 make it possible for class unloaders to fully unload Okio. 735 * New: `Okio.blackhole()` returns a sink where all bytes written are discarded. 736 This is Okio's equivalent of `/dev/null`. 737 * New: Encode a string with any charset using `ByteString.encodeString()` and 738 decode strings in any charset using `ByteString.string()`. Most applications 739 should prefer `ByteString.encodeUtf8()` and `ByteString.utf8()` unless it's 740 necessary to support a legacy charset. 741 * New: `GzipSink.deflater()` makes it possible to configure the compression 742 level. 743 744 745## Version 1.9.0 746 747_2016-07-01_ 748 749 * New: `Pipe` makes it easy to connect a producer thread to a consumer thread. 750 Reads block until data is available to read. Writes block if the pipe's is 751 full. Both sources and sinks support timeouts. 752 * New: `BufferedSource.rangeEquals()` makes it easy to compare a range in a 753 stream to an expected value. This does the right thing: it blocks to load 754 the data required return a definitive result. But it won't block 755 unnecessarily. 756 * New: `Timeout.waitUntilNotified()` makes it possible to use nice timeout 757 abstractions on Java's built-in wait/notify primitives. 758 * Fix: Don't return incorrect results when `HashingSource` does large reads. 759 There was a bug where it wasn't traversing through the segments of the buffer 760 being hashed. This means that `HashingSource` was returning incorrect answers 761 for any writes that spanned multiple segment boundaries. 762 763## Version 1.8.0 764 765_2016-05-02_ 766 767 * New: `BufferedSource.select(Options)` API for reading one of a set of 768 expected values. 769 * New: Make `ByteString.toString()` and `Buffer.toString()` friendlier. 770 These methods return text if the byte string is valid UTF-8. 771 * New: APIs to match byte strings: `indexOf()`, `startsWith()`, and 772 `endsWith()`. 773 774## Version 1.7.0 775 776_2016-04-10_ 777 778 * New: Change the segment size to 8 KiB. This has been reported to dramatically 779 improve performance in some applications. 780 * New: `md5()`, `sha1()`, and `sha256()` methods on `Buffer`. Also add a 781 `sha1()` method on `ByteString` for symmetry. 782 * New: `HashingSource` and `HashingSink`. These classes are Okio’s equivalent 783 to the JDK’s `DigestInputStream` and `DigestOutputStream`. They offer 784 convenient `md5()`, `sha1()`, and `sha256()` factory methods to avoid an 785 impossible `NoSuchAlgorithmException`. 786 * New: `ByteString.asByteBuffer()`. 787 * Fix: Limit snapshot byte strings to requested size. 788 * Fix: Change write timeouts to have a maximum write size. Previously large 789 writes could easly suffer timeouts because the entire write was subject to a 790 single timeout. 791 * Fix: Recover from EBADF failures, which could be triggered by asynchronously 792 closing a stream on older versions of Android. 793 * Fix: Don't share segments if doing so only saves a small copy. This should 794 improve performance for all applications. 795 * Fix: Optimize `BufferedSource.indexOfElement()` and `indexOf(ByteString)`. 796 Previously this method had a bug that caused it to be very slow on large 797 buffers. 798 799## Version 1.6.0 800 801_2015-08-25_ 802 803 * New: `BufferedSource.indexOf(ByteString)` searches a source for the next 804 occurrence of a byte string. 805 * Fix: Recover from unexpected `AssertionError` thrown on Android 4.2.2 and 806 earlier when asynchronously closing a socket. 807 808## Version 1.5.0 809 810_2015-06-19_ 811 812 * Sockets streams now throw `SocketTimeoutException`. This builds on new 813 extension point in `AsyncTimeout` to customize the exception when a timeout 814 occurs. 815 * New: `ByteString` now implements `Comparable`. The comparison sorts bytes as 816 unsigned: {@code ff} sorts after {@code 00}. 817 818## Version 1.4.0 819 820_2015-05-16_ 821 822 * **Timeout exception changed.** Previously `Timeout.throwIfReached()` would 823 throw `InterruptedIOException` on thread interruption, and `IOException` if 824 the deadline was reached. Now it throws `InterruptedIOException` in both 825 cases. 826 * Fix: throw `EOFException` when attempting to read digits from an empty 827 source. Previously this would crash with an unchecked exception. 828 * New: APIs to read and write UTF-8 code points without allocating strings. 829 * New: `BufferedSink` can now write substrings directly, potentially saving an 830 allocation for some callers. 831 * New: `ForwardingTimeout` class. 832 833## Version 1.3.0 834 835_2015-03-16_ 836 837 * New: Read and write signed decimal and unsigned hexadecimal values in 838 `BufferedSource` and `BufferedSink`. Unlike the alternatives, these methods 839 don’t do any memory allocations! 840 * New: Segment sharing. This improves the runtime of operations like 841 `Buffer.clone()` and `Buffer.copyTo()` by sharing underlying segments between 842 buffers. 843 * New: `Buffer.snapshot()` returns an immutable snapshot of a buffer as a 844 `ByteString`. This builds on segment sharing so that snapshots are shallow, 845 immutable copies. 846 * New: `ByteString.rangeEquals()`. 847 * New: `ByteString.md5()` and `ByteString.sha256()`. 848 * New: `ByteString.base64Url()` returns URL-safe Base64. The existing 849 decoding method has been extended to support URL-safe Base64 input. 850 * New: `ByteString.substring()` returns a prefix, infix, or suffix. 851 * New: `Sink` now implements `java.io.Flushable`. 852 * Fix: `Buffer.write(Source, long)` now always writes fully. The previous 853 behavior would return as soon as any data had been written; this was 854 inconsistent with all other _write()_ methods in the API. 855 * Fix: don't leak empty segments in DeflaterSink and InflaterSource. (This was 856 unlikely to cause problems in practice.) 857 858## Version 1.2.0 859 860_2014-12-30_ 861 862 * Fix: `Okio.buffer()` _always_ buffers for better predictability. 863 * Fix: Provide context when `readUtf8LineStrict()` throws. 864 * Fix: Buffers do not call through the `Source` on zero-byte writes. 865 866## Version 1.1.0 867 868_2014-12-11_ 869 870 * Do UTF-8 encoding natively for a performance increase, particularly on Android. 871 * New APIs: `BufferedSink.emit()`, `BufferedSource.request()` and `BufferedSink.indexOfElement()`. 872 * Fixed a performance bug in `Buffer.indexOf()` 873 874## Version 1.0.1 875 876_2014-08-08_ 877 878 * Added `read(byte[])`, `read(byte[], offset, byteCount)`, and 879 `void readFully(byte[])` to `BufferedSource`. 880 * Refined declared checked exceptions on `Buffer` methods. 881 882 883## Version 1.0.0 884 885_2014-05-23_ 886 887 * Bumped release version. No other changes! 888 889## Version 0.9.0 890 891_2014-05-03_ 892 893 * Use 0 as a sentinel for no timeout. 894 * Make AsyncTimeout public. 895 * Remove checked exception from Buffer.readByteArray. 896 897## Version 0.8.0 898 899_2014-04-24_ 900 901 * Eagerly verify preconditions on public APIs. 902 * Quick return on Buffer instance equivalence. 903 * Add delegate types for Sink and Source. 904 * Small changes to the way deadlines are managed. 905 * Add append variant of Okio.sink for File. 906 * Methods to exhaust BufferedSource to byte[] and ByteString. 907 908## Version 0.7.0 909 910_2014-04-18_ 911 912 * Don't use getters in timeout. 913 * Use the watchdog to interrupt sockets that have reached deadlines. 914 * Add java.io and java.nio file source/sink helpers. 915 916## Version 0.6.1 917 918_2014-04-17_ 919 920 * Methods to read a buffered source fully in UTF-8 or supplied charset. 921 * API to read a byte[] directly. 922 * New methods to move all data from a source to a sink. 923 * Fix a bug on input stream exhaustion. 924 925## Version 0.6.0 926 927_2014-04-15_ 928 929 * Make ByteString serializable. 930 * New API: `ByteString.of(byte[] data, int offset, int byteCount)` 931 * New API: stream-based copy, write, and read helpers. 932 933## Version 0.5.0 934 935_2014-04-08_ 936 937 * Initial public release. 938 * Imported from OkHttp. 939 940 941[bom]: https://docs.gradle.org/6.2/userguide/platforms.html#sub:bom_import 942[datetime_0_3_0]: https://github.com/Kotlin/kotlinx-datetime/releases/tag/v0.3.0 943[gradle_metadata]: https://blog.gradle.org/gradle-metadata-1.0 944[hierarchical_projects]: https://kotlinlang.org/docs/multiplatform-hierarchy.html 945[kotlin_1_4_10]: https://github.com/JetBrains/kotlin/releases/tag/v1.4.10 946[kotlin_1_4_20]: https://github.com/JetBrains/kotlin/releases/tag/v1.4.20 947[kotlin_1_5_20]: https://github.com/JetBrains/kotlin/releases/tag/v1.5.20 948[kotlin_1_5_31]: https://github.com/JetBrains/kotlin/releases/tag/v1.5.31 949[kotlin_1_6_20]: https://blog.jetbrains.com/kotlin/2022/04/kotlin-1-6-20-released/ 950[kotlin_1_8_0]: https://kotlinlang.org/docs/whatsnew18.html 951[kotlin_1_9_0]: https://kotlinlang.org/docs/whatsnew19.html 952[kotlin_1_9_10]: https://github.com/JetBrains/kotlin/releases/tag/v1.9.10 953[kotlin_1_9_21]: https://github.com/JetBrains/kotlin/releases/tag/v1.9.21 954[loom]: https://wiki.openjdk.org/display/loom/Getting+started 955[maven_provided]: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html 956[preview1]: https://github.com/WebAssembly/WASI/blob/main/legacy/preview1/docs.md 957[watchosX86]: https://blog.jetbrains.com/kotlin/2023/02/update-regarding-kotlin-native-targets/ 958[xor_utf8]: https://github.com/square/okio/blob/bbb29c459e5ccf0f286e0b17ccdcacd7ac4bc2a9/okio/src/main/kotlin/okio/Utf8.kt#L302 959