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