1*ab625e41SAndroid Build Coastguard WorkerOkio 2*ab625e41SAndroid Build Coastguard Worker==== 3*ab625e41SAndroid Build Coastguard Worker 4*ab625e41SAndroid Build Coastguard WorkerOkio is a new library that complements `java.io` and `java.nio` to make it much 5*ab625e41SAndroid Build Coastguard Workereasier to access, store, and process your data. 6*ab625e41SAndroid Build Coastguard Worker 7*ab625e41SAndroid Build Coastguard WorkerByteStrings and Buffers 8*ab625e41SAndroid Build Coastguard Worker----------------------- 9*ab625e41SAndroid Build Coastguard Worker 10*ab625e41SAndroid Build Coastguard WorkerOkio is built around two types that pack a lot of capability into a 11*ab625e41SAndroid Build Coastguard Workerstraightforward API: 12*ab625e41SAndroid Build Coastguard Worker 13*ab625e41SAndroid Build Coastguard Worker * [**ByteString**][3] is an immutable sequence of bytes. For character data, `String` 14*ab625e41SAndroid Build Coastguard Worker is fundamental. `ByteString` is String's long-lost brother, making it easy to 15*ab625e41SAndroid Build Coastguard Worker treat binary data as a value. This class is ergonomic: it knows how to encode 16*ab625e41SAndroid Build Coastguard Worker and decode itself as hex, base64, and UTF-8. 17*ab625e41SAndroid Build Coastguard Worker 18*ab625e41SAndroid Build Coastguard Worker * [**Buffer**][4] is a mutable sequence of bytes. Like `ArrayList`, you don't need 19*ab625e41SAndroid Build Coastguard Worker to size your buffer in advance. You read and write buffers as a queue: write 20*ab625e41SAndroid Build Coastguard Worker data to the end and read it from the front. There's no obligation to manage 21*ab625e41SAndroid Build Coastguard Worker positions, limits, or capacities. 22*ab625e41SAndroid Build Coastguard Worker 23*ab625e41SAndroid Build Coastguard WorkerInternally, `ByteString` and `Buffer` do some clever things to save CPU and 24*ab625e41SAndroid Build Coastguard Workermemory. If you encode a UTF-8 string as a `ByteString`, it caches a reference to 25*ab625e41SAndroid Build Coastguard Workerthat string so that if you decode it later, there's no work to do. 26*ab625e41SAndroid Build Coastguard Worker 27*ab625e41SAndroid Build Coastguard Worker`Buffer` is implemented as a linked list of segments. When you move data from 28*ab625e41SAndroid Build Coastguard Workerone buffer to another, it _reassigns ownership_ of the segments rather than 29*ab625e41SAndroid Build Coastguard Workercopying the data across. This approach is particularly helpful for multithreaded 30*ab625e41SAndroid Build Coastguard Workerprograms: a thread that talks to the network can exchange data with a worker 31*ab625e41SAndroid Build Coastguard Workerthread without any copying or ceremony. 32*ab625e41SAndroid Build Coastguard Worker 33*ab625e41SAndroid Build Coastguard WorkerSources and Sinks 34*ab625e41SAndroid Build Coastguard Worker----------------- 35*ab625e41SAndroid Build Coastguard Worker 36*ab625e41SAndroid Build Coastguard WorkerAn elegant part of the `java.io` design is how streams can be layered for 37*ab625e41SAndroid Build Coastguard Workertransformations like encryption and compression. Okio includes its own stream 38*ab625e41SAndroid Build Coastguard Workertypes called [`Source`][5] and [`Sink`][6] that work like `InputStream` and 39*ab625e41SAndroid Build Coastguard Worker`OutputStream`, but with some key differences: 40*ab625e41SAndroid Build Coastguard Worker 41*ab625e41SAndroid Build Coastguard Worker * **Timeouts.** The streams provide access to the timeouts of the underlying 42*ab625e41SAndroid Build Coastguard Worker I/O mechanism. Unlike the `java.io` socket streams, both `read()` and 43*ab625e41SAndroid Build Coastguard Worker `write()` calls honor timeouts. 44*ab625e41SAndroid Build Coastguard Worker 45*ab625e41SAndroid Build Coastguard Worker * **Easy to implement.** `Source` declares three methods: `read()`, `close()`, 46*ab625e41SAndroid Build Coastguard Worker and `timeout()`. There are no hazards like `available()` or single-byte reads 47*ab625e41SAndroid Build Coastguard Worker that cause correctness and performance surprises. 48*ab625e41SAndroid Build Coastguard Worker 49*ab625e41SAndroid Build Coastguard Worker * **Easy to use.** Although _implementations_ of `Source` and `Sink` have only 50*ab625e41SAndroid Build Coastguard Worker three methods to write, _callers_ are given a rich API with the 51*ab625e41SAndroid Build Coastguard Worker [`BufferedSource`][7] and [`BufferedSink`][8] interfaces. These interfaces give you 52*ab625e41SAndroid Build Coastguard Worker everything you need in one place. 53*ab625e41SAndroid Build Coastguard Worker 54*ab625e41SAndroid Build Coastguard Worker * **No artificial distinction between byte streams and char streams.** It's all 55*ab625e41SAndroid Build Coastguard Worker data. Read and write it as bytes, UTF-8 strings, big-endian 32-bit integers, 56*ab625e41SAndroid Build Coastguard Worker little-endian shorts; whatever you want. No more `InputStreamReader`! 57*ab625e41SAndroid Build Coastguard Worker 58*ab625e41SAndroid Build Coastguard Worker * **Easy to test.** The `Buffer` class implements both `BufferedSource` and 59*ab625e41SAndroid Build Coastguard Worker `BufferedSink` so your test code is simple and clear. 60*ab625e41SAndroid Build Coastguard Worker 61*ab625e41SAndroid Build Coastguard WorkerSources and sinks interoperate with `InputStream` and `OutputStream`. You can 62*ab625e41SAndroid Build Coastguard Workerview any `Source` as an `InputStream`, and you can view any `InputStream` as a 63*ab625e41SAndroid Build Coastguard Worker`Source`. Similarly for `Sink` and `OutputStream`. 64*ab625e41SAndroid Build Coastguard Worker 65*ab625e41SAndroid Build Coastguard WorkerDependable 66*ab625e41SAndroid Build Coastguard Worker---------- 67*ab625e41SAndroid Build Coastguard Worker 68*ab625e41SAndroid Build Coastguard WorkerOkio started as a component of [OkHttp][1], the capable HTTP+SPDY client 69*ab625e41SAndroid Build Coastguard Workerincluded in Android. It's well-exercised and ready to solve new problems. 70*ab625e41SAndroid Build Coastguard Worker 71*ab625e41SAndroid Build Coastguard Worker 72*ab625e41SAndroid Build Coastguard WorkerExample: a PNG decoder 73*ab625e41SAndroid Build Coastguard Worker---------------------- 74*ab625e41SAndroid Build Coastguard Worker 75*ab625e41SAndroid Build Coastguard WorkerDecoding the chunks of a PNG file demonstrates Okio in practice. 76*ab625e41SAndroid Build Coastguard Worker 77*ab625e41SAndroid Build Coastguard Worker```java 78*ab625e41SAndroid Build Coastguard Workerprivate static final ByteString PNG_HEADER = ByteString.decodeHex("89504e470d0a1a0a"); 79*ab625e41SAndroid Build Coastguard Worker 80*ab625e41SAndroid Build Coastguard Workerpublic void decodePng(InputStream in) throws IOException { 81*ab625e41SAndroid Build Coastguard Worker BufferedSource pngSource = Okio.buffer(Okio.source(in)); 82*ab625e41SAndroid Build Coastguard Worker 83*ab625e41SAndroid Build Coastguard Worker ByteString header = pngSource.readByteString(PNG_HEADER.size()); 84*ab625e41SAndroid Build Coastguard Worker if (!header.equals(PNG_HEADER)) { 85*ab625e41SAndroid Build Coastguard Worker throw new IOException("Not a PNG."); 86*ab625e41SAndroid Build Coastguard Worker } 87*ab625e41SAndroid Build Coastguard Worker 88*ab625e41SAndroid Build Coastguard Worker while (true) { 89*ab625e41SAndroid Build Coastguard Worker Buffer chunk = new Buffer(); 90*ab625e41SAndroid Build Coastguard Worker 91*ab625e41SAndroid Build Coastguard Worker // Each chunk is a length, type, data, and CRC offset. 92*ab625e41SAndroid Build Coastguard Worker int length = pngSource.readInt(); 93*ab625e41SAndroid Build Coastguard Worker String type = pngSource.readUtf8(4); 94*ab625e41SAndroid Build Coastguard Worker pngSource.readFully(chunk, length); 95*ab625e41SAndroid Build Coastguard Worker int crc = pngSource.readInt(); 96*ab625e41SAndroid Build Coastguard Worker 97*ab625e41SAndroid Build Coastguard Worker decodeChunk(type, chunk); 98*ab625e41SAndroid Build Coastguard Worker if (type.equals("IEND")) break; 99*ab625e41SAndroid Build Coastguard Worker } 100*ab625e41SAndroid Build Coastguard Worker 101*ab625e41SAndroid Build Coastguard Worker pngSource.close(); 102*ab625e41SAndroid Build Coastguard Worker} 103*ab625e41SAndroid Build Coastguard Worker 104*ab625e41SAndroid Build Coastguard Workerprivate void decodeChunk(String type, Buffer chunk) { 105*ab625e41SAndroid Build Coastguard Worker if (type.equals("IHDR")) { 106*ab625e41SAndroid Build Coastguard Worker int width = chunk.readInt(); 107*ab625e41SAndroid Build Coastguard Worker int height = chunk.readInt(); 108*ab625e41SAndroid Build Coastguard Worker System.out.printf("%08x: %s %d x %d%n", chunk.size(), type, width, height); 109*ab625e41SAndroid Build Coastguard Worker } else { 110*ab625e41SAndroid Build Coastguard Worker System.out.printf("%08x: %s%n", chunk.size(), type); 111*ab625e41SAndroid Build Coastguard Worker } 112*ab625e41SAndroid Build Coastguard Worker} 113*ab625e41SAndroid Build Coastguard Worker``` 114*ab625e41SAndroid Build Coastguard Worker 115*ab625e41SAndroid Build Coastguard WorkerDownload 116*ab625e41SAndroid Build Coastguard Worker-------- 117*ab625e41SAndroid Build Coastguard Worker 118*ab625e41SAndroid Build Coastguard WorkerDownload [the latest JAR][2] or grab via Maven: 119*ab625e41SAndroid Build Coastguard Worker```xml 120*ab625e41SAndroid Build Coastguard Worker<dependency> 121*ab625e41SAndroid Build Coastguard Worker <groupId>com.squareup.okio</groupId> 122*ab625e41SAndroid Build Coastguard Worker <artifactId>okio</artifactId> 123*ab625e41SAndroid Build Coastguard Worker <version>1.6.0</version> 124*ab625e41SAndroid Build Coastguard Worker</dependency> 125*ab625e41SAndroid Build Coastguard Worker``` 126*ab625e41SAndroid Build Coastguard Workeror Gradle: 127*ab625e41SAndroid Build Coastguard Worker```groovy 128*ab625e41SAndroid Build Coastguard Workercompile 'com.squareup.okio:okio:1.6.0' 129*ab625e41SAndroid Build Coastguard Worker``` 130*ab625e41SAndroid Build Coastguard Worker 131*ab625e41SAndroid Build Coastguard WorkerSnapshots of the development version are available in [Sonatype's `snapshots` repository][snap]. 132*ab625e41SAndroid Build Coastguard Worker 133*ab625e41SAndroid Build Coastguard Worker 134*ab625e41SAndroid Build Coastguard Worker [1]: https://github.com/square/okhttp 135*ab625e41SAndroid Build Coastguard Worker [2]: https://search.maven.org/remote_content?g=com.squareup.okio&a=okio&v=LATEST 136*ab625e41SAndroid Build Coastguard Worker [3]: http://square.github.io/okio/okio/ByteString.html 137*ab625e41SAndroid Build Coastguard Worker [4]: http://square.github.io/okio/okio/Buffer.html 138*ab625e41SAndroid Build Coastguard Worker [5]: http://square.github.io/okio/okio/Source.html 139*ab625e41SAndroid Build Coastguard Worker [6]: http://square.github.io/okio/okio/Sink.html 140*ab625e41SAndroid Build Coastguard Worker [7]: http://square.github.io/okio/okio/BufferedSource.html 141*ab625e41SAndroid Build Coastguard Worker [8]: http://square.github.io/okio/okio/BufferedSink.html 142*ab625e41SAndroid Build Coastguard Worker [snap]: https://oss.sonatype.org/content/repositories/snapshots/ 143