首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >读取OKIO流两次

读取OKIO流两次
EN

Stack Overflow用户
提问于 2016-01-25 23:49:48
回答 1查看 713关注 0票数 1

我正在使用OKHTTP进行网络连接,目前从response.charStream()获取了一个charStream,然后将其传递给GSON进行解析。在解析和膨胀之后,我再次压缩模型以使用流保存到磁盘。从networkReader到模型再到DiskWriter,这似乎是一项额外的工作。有没有可能使用OKIO从networkReader转到JSONParser(阅读器),以及从networkReader转到DiskWriter(阅读器)。基本上,我希望能够从网络流中读取两次。

EN

回答 1

Stack Overflow用户

发布于 2016-09-29 05:04:04

您可以使用MirroredSource (取自this gist)。

代码语言:javascript
复制
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 */ }
        };
    }
}

用法如下所示:

代码语言:javascript
复制
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();

如果你想要更健壮的东西,你可以从OkHttp重新调整Relay的用途。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34996673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档