Writing "raw" data using JsonWriter
See original GitHub issueHi, 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
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:5 (2 by maintainers)
Top GitHub Comments
Here is a very ugly (but working…) implementation.
I’m hoping for an already built-in method to do this kind of behaviour
d