google / google/gson

Writing "raw" data using JsonWriter

Open
#1,367 5 comments 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Java
Stars
24.2k
Forks
4.5k
Avg merge
6d 4h
Merged PRs (30d)
12

Description

Hi,
I have a flow which read an image from a File, convert it to Base64, put the value inside a JSON and then write the data inside an OutputStream (which will send content using an HTTP Connection).

Due to image size, I can't read the whole image bytes in memory, then fully convert it to base64, then put it all the base64 value inside the json and create the connection.

So I'm using a JsonWriter in order to read a chunk of data, convert it to base64, write inside the outputstream and the repeat for the whole content of the image. Here is concept code:

```
@Override
public void writeTo(OutputStream out) throws IOException {
try (JsonWriter jsonWriter = new JsonWriter(new OutputStreamWriter(out, "UTF-8"))) {
jsonWriter.beginObject();
jsonWriter.name("image_base64");

// Read the image file with buffer
Encoder encoder = Base64.getEncoder();
ByteBuffer bytes = ByteBuffer.allocate(64 * 1024);
ReadChannel reader = client.reader(... opening reader for file...);

// TODO1
jsonWriter.beginString();

while (reader.read(bytes) > 0) {
bytes.flip();
// TODO2
jsonWriter.appendStringValue(encoder.encode(bytes.array()));
bytes.clear();
}
// TODO3
jsonWriter.endStringValue();

jsonWriter.endObject();
}
}
```

Because the JsonWriter only provides the method to write an entire String, for the moment the only way I found is reading the whole image, convert it to a full String and the call a single method.
As mentioned in the opening, I need to do this processing with a buffer in order to not having alla the image bytes in memory. Please note the 3 `TODO` parts, which I'm not sure how to implement.

Is there a way to write "raw data" in the OutputStream which simply writes the characters I give to it instead of writing the exact String i give, sorrounded by "?

For the moment I totally ignored the JsonWriter implementation and I'm writing the whole content as raw data:
```
@Override
public void writeTo(OutputStream out) throws IOException {
String init = "{\"image_bytes\":{\"";
out.write(init.getBytes(Charset.forName("UTF-8")));

Encoder encoder = Base64.getEncoder();
try ( OutputStream outB64 = encoder.wrap(out)){
ReadChannel reader = client.reader(... opening reader for file...);
IOUtils.copy(Channels.newInputStream(reader), outB64,64 * 1024);
}

String end = "\"}";
out.write(end.getBytes(Charset.forName("UTF-8")));
}
```

Please note that this is a simplified version, the real json also have additional values as metadata for the image and other stuffs

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.