私はネットワークに OKHTTP を使用しており、現在、response.charStream() から charStream を取得しています。これを解析のために GSON に渡します。解析して膨張させたら、モデルを再び収縮させて、ストリームを使用してディスクに保存します。networkReader から Model、DiskWriter に移動する必要があるのは余分な作業のようです。OKIOを使用して、代わりにnetworkReaderからJSONParser(reader)、およびnetworkReaderからDiskWriter(reader)に移動することは可能ですか? 基本的に、ネットワーク ストリームから 2 回読み取れるようにしたいと考えています。
質問する
728 次
1 に答える
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 から再利用できます。
于 2016-09-28T21:04:03.503 に答える