Skip to content Skip to sidebar Skip to footer

Streaming Upload Of A Base64 Image Using Retrofit

I have an upstream server that accepts image submissions using rest. The submitted image is part of a JSON payload similar to this one { 'name': 'Blah.jpg', 'uploader': 'user1'

Solution 1:

Not with Gson or Moshi. Both of these libraries require strings to be in memory before emitting them to a stream.

Solution 2:

I solved this with the following, in a class that extends okhttp3.RequestBody:

privatevoidwriteFile(File file, BufferedSink sink)throws IOException {
    byte buf[] = newbyte[3000];
    try (FileInputStreamfin=newFileInputStream(file)) {
        while (fin.read(buf) >= 0) {
            byte encoded[] = Base64.encodeBase64(buf);
            sink.write(encoded);
        }
    }
}

It uses Android's android.util.Base64 Apache Commons' org.apache.commons.codec.binary.Base64 to encode a buffered chunk of data.

I ended up writing the other json fields separately, with enough granularity that I could insert the file record exactly where I needed to.

EDIT:

As you can see in my edits above, I ended up switching to Apache commons-codec, via compile 'commons-codec:commons-codec:1.5' in my build.gradle file.

I didn't have time to investigate why the Android SDK solution didn't work. I tried their Base64.encode(buf, Base64.NO_WRAP) as suggested elsewhere - supposedly equivalent to Apache Commons' encodeBase64(byte[]) - but this did not work, hence the switch.

The problem could have been on our backend, so don't rule out Android SDK's solution based on my post alone - I just wanted to add this note so readers can see the code snippet that actually worked for me in the end.

Post a Comment for "Streaming Upload Of A Base64 Image Using Retrofit"