question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Writing "raw" data using JsonWriter

See original GitHub issue

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

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:1
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
NicolaSpreaficocommented, Aug 11, 2018

Here is a very ugly (but working…) implementation.

public static void main(String[] args) {
        try {
            String[] parts = {"foo", "bar", "baz" /* this array simulates all the chunks of data to write */ };

            try (MyJsonWriter writer = new MyJsonWriter(new PrintWriter(System.out))) {
                writer.beginObject();

                writer.name("key");

                // Fake value in order to make the json structure balanced, it does not write any data
                writer.jsonValue("");

                writer.raw("\"");

                for (String part : parts) {
                    writer.raw(part);
                }

                writer.raw("\"");

                writer.endObject();
            }
        } catch (Exception e) {
            System.err.println("\n\n");
            e.printStackTrace();
        }
    }

    public static class MyJsonWriter extends JsonWriter {
        private Writer out;

        public MyJsonWriter(Writer out) {
            super(out);
            this.out = out;
        }

        public MyJsonWriter raw(String raw) throws IOException {
            this.out.write(raw);
            return this;
        }
    }

I’m hoping for an already built-in method to do this kind of behaviour

0reactions
KhunFirstcommented, Aug 12, 2018

d

Read more comments on GitHub >

github_iconTop Results From Across the Web

JsonWriter Class - Json.NET
Asynchronously writes raw JSON where a value is expected and updates the writer's state. Public method, WriteStartArray. Writes the beginning of a JSON...
Read more >
JsonWriter - Android Developers
To encode your data as JSON, create a new JsonWriter . Each JSON document must contain one ... Each JsonWriter may be used...
Read more >
How to Write a JSON Into a File in C# - Code Maze
We are going to explore different ways of writing JSON data to a file using the inbuilt System.Text.Json library and the popular Newtonsoft....
Read more >
JSONWriter - JSON | Reference - Particle docs
Using JSONWriter the code is much easier to read: ... It the data is truncated, then zeroing out at offset writer.dataSize() will write...
Read more >
JsonWriter - Go Packages
JsonWriter can serialize strings, ints (unsigned/signed, ... Star an array with the given key ... func (w *Writer) Raw(data []byte).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found