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.

Support for retrieving incomplete string/bytes from an InputStream when EOF is reached

See original GitHub issue

I have an InputStream which may have some additional characters at the end (incomplete json object string) which I want to retrieve after reading a bunch of json values.

To elaborate: I have an InputStream for reading a large file, but due to throttling reasons, the InputStream sends and EOF after a pre-defined number of bytes are transferred. In other words, I have a large file, which lets me open InputStreams for reading 100MB or data at a time. When the 100MB limit is reached, the stream ends, and you need to create a new InputStream for the next “block” / “page”.

Due to this model, the stream may end with a json object split across 2 blocks. I need to be able to handle this while reading.

I was referring to #1304 which helped me solve how to read values from an input stream.

Here’s a small piece of code as an example

        var json = "  {\"a\":{\"b\":[{\"c\":1}\n]}}   { \"a\" : 1}\n{ \"b\" : 1} {} {\"x";
        var input = new ByteArrayInputStream(json.getBytes());
        var reader = Util.getObjectMapper().readerFor(Object.class);
        var iterator = reader.readValues(input);
        Iterable<Object> iterable = () -> iterator;
        try {
            for (var x : iterable) {
                print(x);
            }
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
        print("Left: " + new String(input.readAllBytes()));

Here’s the output of the above:

{a={b=[{c=1}]}}
{a=1}
{b=1}
{}
java.lang.RuntimeException: Unexpected end-of-input in field name
 at [Source: (ByteArrayInputStream); line: 3, column: 18]
	at com.fasterxml.jackson.databind.MappingIterator._handleIOException(MappingIterator.java:417)
	at com.fasterxml.jackson.databind.MappingIterator.next(MappingIterator.java:203)
	at Scratch.main(scratch.java:24)
Caused by: com.fasterxml.jackson.core.io.JsonEOFException: Unexpected end-of-input in field name
 at [Source: (ByteArrayInputStream); line: 3, column: 18]
	at com.fasterxml.jackson.core.base.ParserMinimalBase._reportInvalidEOF(ParserMinimalBase.java:662)
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.parseEscapedName(UTF8StreamJsonParser.java:2020)
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.slowParseName(UTF8StreamJsonParser.java:1925)
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser._parseName(UTF8StreamJsonParser.java:1709)
	at com.fasterxml.jackson.core.json.UTF8StreamJsonParser.nextToken(UTF8StreamJsonParser.java:766)
	at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializer$Vanilla.deserialize(UntypedObjectDeserializer.java:707)
	at com.fasterxml.jackson.databind.MappingIterator.nextValue(MappingIterator.java:280)
	at com.fasterxml.jackson.databind.MappingIterator.next(MappingIterator.java:199)
	... 1 more
Left: 

As can be seen, the entire stream has been consumed. Is there any buffer that Jackson stores this in to be able to retrieve from ?

I’m trying to retrieve the unresolved part of the InputStream and prefix it to the next one (using something like SequenceInputStream).

Any way I can do this ?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:11 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
cowtowncodercommented, Apr 15, 2021

While there is on-going work, I think this specific issue turned out to be bit of misunderstanding between what can be retrieved (non-consumed content) and what would be expected (all content for which token has not been produced, including possible partial token content consumed and indicated in exception message).

0reactions
the-codinatorcommented, Apr 6, 2021

Thanks, your concern is very true. Any path that circumvents the counting operations (even unintentionally) will instantly cause failures in the entire logic. This approach is highly dependent on the reliability of said counts.

I will thoroughly test this with our actual use-case to make sure it works. Simultaneously, I’ll continue checking for possibly more reliable alternatives.

Read more comments on GitHub >

github_iconTop Results From Across the Web

InputStream not receiving EOF - Stack Overflow
Firstly, I think you misunderstood the meaning of EOF (-1). It doesn't mean the server wrote a -1, it means the server closed...
Read more >
Data return from InputStream is incomplete — oracle-tech
Hi Everyone, I face a very strange behavior of InputStream class object. When I try to convert inputStreamObject into String data using the...
Read more >
Kotlin Language Documentation 1.7.21
Start from scratch. Dive deep into Kotlin Multiplatform. Get help. Understand Multiplatform project structure. Multiplatform plugin. Targets.
Read more >
Repository Objects Reference - SAP Help Portal
Get and filter data by the given SQL statement from. SAP BTP Open. Connectors. Active. Connectivity (via. Flowagent) [page.
Read more >
Read a file using InputStream in Java | Techie Delight
InputStream's read() method reads a byte of data from the input stream. It returns the next byte of data, or -1 if the...
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