0

取款机有点问题。对于我的“inapp”-更新即时通讯从我的网络空间下载新的 base64 编码的 .apk。我的功能差不多了,这是没有解码的代码。

            public void onResponse(Call call, Response response) throws IOException {
            if(response.isSuccessful()){
                ResponseBody body = response.body();
                BufferedSource source = body.source();
                source.request(Long.MAX_VALUE);
                Buffer buffer = source.buffer();

                String rString = buffer.clone().readString(Charset.forName("UTF-8"));
                Log.i("Test: ", AppUtils.decodeBase64(rString));

                if(rString.equals("xxx")){
                    EventBus.getDefault().post(new KeyNotValid());
                    dispatcher.cancelAll();
                }else{
                    EventBus.getDefault().post(new SaveKey(apikey));
                    BufferedSink sink = Okio.buffer(Okio.sink(myFile));
                    sink.writeAll(source);
                    sink.flush();
                    sink.close();
                }
            }
        }

Buffer/Log 并不是真正需要的,只是在测试期间使用它来检查响应。

在将字节写入接收器之前,我将如何解码它们?我尝试通过这样做。ByteString,但我找不到将解码的字符串写回 BufferedSource 的方法。

大多数替代方案都非常慢,例如之后重新打开文件,将字节读入内存,解码并将它们写回。

非常感谢您对此的任何帮助

干杯

4

2 回答 2

0

我知道这个答案来得很晚,而且 Yuri 的答案在技术上是正确的,但我认为最惯用的方法是利用 Okio 推广的组合模式来创建一个Source从 Base64 解码的(或Sink编码为 Base64的,如果你需要的话)。

这是一个小概念证明(我相信它可以改进):

public class Base64Source implements Source {

    private Source delegate;
    private Base64.Decoder decoder; // Using Java 8 API, but it can be any library

    public Base64Source(Source delegate) {
        this(delegate, Base64.getDecoder());
    }

    public Base64Source(Source delegate, Base64.Decoder decoder) {
        this.delegate = delegate;
        this.decoder = decoder;
    }

    @Override
    public long read(Buffer sink, long byteCount) throws IOException {
        Buffer buffer = new Buffer();
        long actualRead = this.delegate.read(buffer, byteCount);
        if (actualRead == -1) {
            return -1;
        }

        byte[] encoded = buffer.readByteArray(actualRead);
        byte[] decoded = decoder.decode(encoded);
        sink.write(decoded);

        return decoded.length;
    }

    @Override
    public Timeout timeout() {
        return this.delegate.timeout();
    }

    @Override
    public void close() throws IOException {
        this.delegate.close();
    }
}

这是它的使用方法

BufferedSource source = Okio.buffer(new Base64Source(originalSource));
BufferedSink sink = ... // create sink
sink.writeAll(source);

// Don't forget to close the source/sink to flush and free resources
sink.close();
source.close();
于 2018-02-27T11:25:56.570 回答
0

您已经可以通过 ResponseBody.byteStream 将响应作为 InputStream 使用。您可以使用https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64InputStream.html装饰此流,并使用它来读取字节流并将其写入以块为单位的文件的接收器。

于 2018-01-03T07:46:53.737 回答