okio 简单使用总结

概述


基本特性

okio 是对 Java IO/NIO非常优秀的封装,“短小精焊”,不仅支持文件读写,也支持Socket读写;
不用区分字符流或者字节流,只有一个输入流Source和一个输出流Sink,使用简单;
提供丰富的API,支持各种类型数据读写;
优秀的缓冲机制和处理内存的技巧,使I/O在缓冲区得到更高的复用处理,从而尽量减少I/O的实际发生。

核心基础类

ByteString:不可变的字节序列,可以很容易地将字节数组当作一个值来处理。
Buffer:可变的字节序列,可灵活访问,插入与移除,不需要自己去动手管理,内部维护 Segment 双项链表实现。


Okio自己的stream类型: SourceSink ,分别类似于java的 InputstreamOutputstream,提供简单的接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface Source : java.io.Closeable {
public abstract fun close(): kotlin.Unit

public abstract fun read(sink: okio.Buffer, byteCount: kotlin.Long): kotlin.Long

public abstract fun timeout(): okio.Timeout
}

public interface Sink : java.io.Closeable, java.io.Flushable {
public abstract fun close(): kotlin.Unit

public abstract fun flush(): kotlin.Unit

public abstract fun timeout(): okio.Timeout

public abstract fun write(source: okio.Buffer, byteCount: kotlin.Long): kotlin.Unit
}

通过 BufferedsourceBufferedsink 提供了丰富的数据读写接口, 这两个接口可以满足你所需的一切。具体的实现通过 RealBufferedSourceRealBufferedSink 操作 Buffer 实现。


okio读文件


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void readFromFile(String path) {
try {
Source source = Okio.source(new File(path));
BufferedSource bufferedSource = Okio.buffer(source);

String line;
while ((line = bufferedSource.readUtf8Line()) != null) {
System.out.println(line);
}

bufferedSource.close();
} catch (IOException e) {
e.printStackTrace();
}
}

BufferedSource 提供了丰富的API,可以很方便的读出不同编码格式的内容


okio写文件


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void writeEnvToFile(String path) {
try {
Sink sink = Okio.sink(new File(path));
BufferedSink bufferedSink = Okio.buffer(sink);

for (Map.Entry<String, String> entry : System.getenv().entrySet()) {
bufferedSink.writeUtf8(entry.getKey());
bufferedSink.writeUtf8("=");
bufferedSink.writeUtf8(entry.getValue());
bufferedSink.writeUtf8("\n");
}

bufferedSink.flush();
bufferedSink.close();
} catch (IOException e) {
e.printStackTrace();
}
}

BufferedSource 提供了丰富的API,可以很方便的写入不同编码格式的内容,与 BufferedSource 对应。


对象序列化与反序列化


支持将对象转化为16进制字符串或base64编码,同时支持将16进制或base64编码字符串转化为对象,可用于对象序列化传输。

工具类编写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public class OkioSerializeUtils {
/**
* 对象序列化为16进制字符串
*/
public static <T extends Serializable> String serializeHexString(T obj) {
return serialize(obj).hex();
}

/**
* 对象序列化为base64编码
*/
public static <T extends Serializable> String serializeBase64(T obj) {
return serialize(obj).base64();
}


/**
* base64编码反序列化对象
*/
public static <T extends Serializable> T deserializeBase64(String base64String) {
return deserialize(ByteString.decodeBase64(base64String));
}

/**
* 16进制字符串反序列化对象
*/
public static <T extends Serializable> T deserializeHexString(String hexString) {
return deserialize(ByteString.decodeHex(hexString));
}

/**
* 序列化
*/
private static <T extends Serializable> ByteString serialize(T obj) {
Buffer buffer = new Buffer();
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(buffer.outputStream())) {
objectOutputStream.writeObject(obj);
} catch (IOException e) {
e.printStackTrace();
}
return buffer.readByteString();
}

/**
* 反序列化
*/
private static <T extends Serializable> T deserialize(ByteString byteString) {
Buffer buffer = new Buffer();
buffer.write(byteString);
try (ObjectInputStream objectInputStream = new ObjectInputStream(buffer.inputStream())) {
return (T) objectInputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
}

测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class SerializeTest {
static class TestObj implements Serializable {
private int a;
private int b;

TestObj(int a, int b) {
this.a = a;
this.b = b;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof TestObj)) {
return false;
}
TestObj testObj = (TestObj) obj;
return testObj.a == a && testObj.b == b;
}

@Override
public int hashCode() {
int result = 17;
result = 31 * result + a;
return 31 * result + b;
}

@Override
public String toString() {
return String.format("[TestObj: a=%s, b=%s]", this.a, this.b);
}
}

public static void main(String[] args) {
TestObj testObj = new TestObj(1, 2);
System.out.println("origin obj: " + testObj);
System.out.println("serialize hexString: " + OkioSerializeUtils.serializeHexString(testObj));
System.out.println("serialize base64: " + OkioSerializeUtils.serializeBase64(testObj));
System.out.println("deserialize hexString: " + OkioSerializeUtils.deserializeHexString("aced00057372001a6f6b696f2e53657269616c697a655465737424546573744f626a8719308efba7bd66020002490001614900016278700000000100000002"));
System.out.println("deserialize base64: " + OkioSerializeUtils.deserializeBase64("rO0ABXNyABpva2lvLlNlcmlhbGl6ZVRlc3QkVGVzdE9iaocZMI77p71mAgACSQABYUkAAWJ4cAAAAAEAAAAC"));
}
}

输出结果:

1
2
3
4
5
origin obj: [TestObj: a=1, b=2]
serialize hexString: aced00057372001a6f6b696f2e53657269616c697a655465737424546573744f626a8719308efba7bd66020002490001614900016278700000000100000002
serialize base64: rO0ABXNyABpva2lvLlNlcmlhbGl6ZVRlc3QkVGVzdE9iaocZMI77p71mAgACSQABYUkAAWJ4cAAAAAEAAAAC
deserialize hexString: [TestObj: a=1, b=2]
deserialize base64: [TestObj: a=1, b=2]





文章目录
  1. 1. 概述
  2. 2. okio读文件
  3. 3. okio写文件
  4. 4. 对象序列化与反序列化