Я использую OKHTTP для работы в сети и в настоящее время получаю charStream от response.charStream(), который затем передаю GSON для синтаксического анализа. После синтаксического анализа и раздувания я снова сдуваю модель, чтобы сохранить ее на диск с помощью потока. Кажется, что нужно выполнить дополнительную работу, чтобы перейти от networkReader к Model и DiskWriter. Можно ли с помощью OKIO вместо этого перейти от networkReader к JSONParser (считыватель), а также от networkReader к DiskWriter (считыватель). В основном я хочу иметь возможность читать из сетевого потока дважды.
Чтение потока OKIO дважды
Ответы (1)
Вы можете использовать MirroredSource
(взято из этой сути).
public class MirroredSource {
private final Buffer buffer = new Buffer();
private final Source source;
private final AtomicBoolean sourceExhausted = new AtomicBoolean();
public MirroredSource(final Source source) {
this.source = source;
}
public Source original() {
return new okio.Source() {
@Override
public long read(final Buffer sink, final long byteCount) throws IOException {
final long bytesRead = source.read(sink, byteCount);
if (bytesRead > 0) {
synchronized (buffer) {
sink.copyTo(buffer, sink.size() - bytesRead, bytesRead);
// Notfiy the mirror to continue
buffer.notify();
}
} else {
sourceExhausted.set(true);
}
return bytesRead;
}
@Override
public Timeout timeout() {
return source.timeout();
}
@Override
public void close() throws IOException {
source.close();
sourceExhausted.set(true);
synchronized (buffer) {
buffer.notify();
}
}
};
}
public Source mirror() {
return new okio.Source() {
@Override
public long read(final Buffer sink, final long byteCount) throws IOException {
synchronized (buffer) {
while (!sourceExhausted.get()) {
// only need to synchronise on reads when the source is not exhausted.
if (buffer.request(byteCount)) {
return buffer.read(sink, byteCount);
} else {
try {
buffer.wait();
} catch (final InterruptedException e) {
//No op
}
}
}
}
return buffer.read(sink, byteCount);
}
@Override
public Timeout timeout() {
return new Timeout();
}
@Override
public void close() throws IOException { /* not used */ }
};
}
}
Использование будет выглядеть так:
MirroredSource mirroredSource = new MirroredSource(response.body().source()); //Or however you're getting your original source
Source originalSource = mirroredSource.original();
Source secondSource = mirroredSource.mirror();
doParsing(originalSource);
writeToDisk(secondSource);
originalSource.close();
Если вам нужно что-то более надежное, вы можете перепрофилировать Relay
из OkHttp.
person
James McCracken
schedule
28.09.2016
ха! на самом деле это мой пиар, и у меня все еще было несколько проблем. Вот обновленная версия gist.github.com/digitalbuddha/18019a61a0d15eb9f7f53f03685418bb, над которой сейчас работает Джесси Уилсон. аналогичная реализация для OKHTTP Cache2 https://github.com/square/okhttp/blob/master/okhttp/src/main/java/okhttp3/internal/cache2/Relay.java.
- person FriendlyMikhail; 29.09.2016