2017-06-20 16 views
0

私はrestを使用してイメージの提出を受け付けるアップストリームサーバーを持っています。提出された画像は、この戦略を使用して、この1retrofitを使用したBase64イメージのストリーミングアップロード

{ 
    "name": "Blah.jpg", 
    "uploader": "user1", 
    "image": "<base64.....>" 
} 

に似たJSONペイロードの一部は、小さな画像のために動作しますが、大きな画像上のメモリエラーのうち生成されます。

イメージのbase64コンポーネントをストリーミングすることはできますか?イテレータのようなものを渡します。イテレータはイメージの塊を読み込んでベース64にして、直接ネットワークに送ります。

+1

JSONペイロードでBLOBをラップしないで 'POST'を使って直接ファイルをアップロードすることは可能でしょうか? –

+2

イメージを送信するためにtusを使用することを検討してください。これはそのために設計されており、中断された転送を再開できます。現在のソリューションは実際には最悪ですが、base64文字列はソースイメージより約1.5倍大きいことに注意してください。あなたはtusで画像をアップロードし、あなたのjsonにtusアップロードIDを提供する必要があります – user1209216

+0

コメントありがとうございます。 UpstreamにAPIの再設計を依頼し、@LyubomyrShaydariv氏の言うとおりに直接投稿できるようにすることを考えています。組み込みのbase64イメージの理由は、イメージとイメージのメタデータを渡すために単一のHTTP呼び出しを行うことでした。おそらく、新しいAPIで2つの呼び出しを行う必要があります。 – Lmwangi

答えて

0

私はokhttp3.RequestBodyを拡張するクラスで、次のようでこれを解決:

private void writeFile(File file, BufferedSink sink) throws IOException { 
    byte buf[] = new byte[3000]; 
    try (FileInputStream fin = new FileInputStream(file)) { 
     while (fin.read(buf) >= 0) { 
      byte encoded[] = Base64.encodeBase64(buf); 
      sink.write(encoded); 
     } 
    } 
} 

をそれは、データのバッファリングされたチャンクをエンコードするために Androidの android.util.Base64 Apacheのコモンズのorg.apache.commons.codec.binary.Base64を使用しています。

私は別のjsonフィールドを別々に作成しました。ファイルレコードを必要な場所に正確に挿入できるほどの粒度を持っていました。

EDIT:あなたは上記の私の編集で見ることができるように

、私は私のbuild.gradleファイルにcompile 'commons-codec:commons-codec:1.5'を経て、Apacheのcommons-codecに切り替えることになりました。

Android SDKソリューションがうまくいかなかった理由を調査する時間がありませんでした。私は彼らのBase64.encode(buf, Base64.NO_WRAP)を他の場所で提案したようにしようとしました。おそらくApache CommonsのencodeBase64(byte[])と同等ですが、これはうまくいきません。

問題は私たちのバックエンドにあった可能性がありますので、私の投稿だけに基づいてAndroid SDKのソリューションを除外しないでください - 私はこのメモを追加して、読者は実際に私のために働いた。

1

GsonまたはMoshiではありません。これらのライブラリの両方とも、ストリングに出力する前にストリングをメモリに格納する必要があります。

関連する問題