4

I'm reading an unknown number of objects from a gzipped file in Kryo:

Input input = new Input(new GZIPInputStream(Files.newInputStream(inputFile)));

The problem is: How do I detect when I've read the last object from the file? When I'm writing the objects I don't know in advance how many I will be writing, so I can't include a count of the objects at the start of the file.

I could have some kind of "dummy" object that I write at the end of the file to indicate that it's the last one, but that seems ugly.

sanity
  • 35,347
  • 40
  • 135
  • 226

3 Answers3

3

Use Input#eof() after reading each object to check if you hit the end of the stream.

NateS
  • 5,751
  • 4
  • 49
  • 59
1

For some reason, input.eof() does not effectively detect EOF, for example, this code resulted in com.esotericsoftware.kryo.KryoException: Buffer underflow.

while (!input.eof())
{
    SomeClass someObject = kryo.readObject(input, SomeClass.class);
    // ...
}

As a workaround, I did something like this:

while (true)
{
    try
    {
        SomeClass someObject = kryo.readObject(input, SomeClass.class);
        // ...
    }
    catch(KryoException ke)
    {
        break;
    }
}

EDIT: I was using the jar version 2.21, but eof worked with 2.22.cloudera.1.

Muffintop
  • 543
  • 4
  • 11
  • Did you see this `Buffer underflow` ever since? I'm using 2.22 version but it seems the exception is still here. It appears from time to time. The code is not run from multiple threads. @NateS, any hints? – dcernahoschi Mar 12 '14 at 12:31
1

For latest (3.0.3) kryo libraries you can use input.eof(). For older ones use input.available() with a cost of performance (Almost 8 times slower).

while(input.available() > 0){
  someObject = kryo.readObject(input, SomeClass.class);
  i++;
}
Atul Soman
  • 4,612
  • 4
  • 30
  • 45