0

anyway to check if method readObject of class ObjectInputStream has finished reading file other than catching its thrown exceptions?

and if no. how can I make outNewmast.writeObject(accountRecord); statement reached in this case?

// read oldmast.ser
    try {
        while (true) {
            accountRecord = (AccountRecord) inOldmast.readObject();
            //read trans.ser
            while (true) {
                transactionRecord = (TransactionRecord) inTrans.readObject();
                if (transactionRecord.getAccountNumber() == accountRecord.getAccount()) {
                    accountRecord.combine(transactionRecord);
                }//end if
            }//end inner while
            outNewmast.writeObject(accountRecord);
        }//end while
    }//end try 
    catch (ClassNotFoundException e) {
        System.err.println("Error reading file.");
        System.exit(1);
    }//end catch         
    catch (IOException e) {
        System.err.println("Error reading file.");
        System.exit(1);
    }//end catch

2 Answers 2

2

The best idea would be to serialize the number of elements beforehand, so you could just do:

cnt = file.readInt();
for (int i=0;i<cnt;i++) {
   file.readObject();
}

The method proposed by @ChrisCooper is not reliable, as stated in documentation. Some streams don't implement it, or return approximate result (in theory, it can even return 0 when there is still some data. Example - network stream).

Therefore, looking at same documentation, we find this particular block:

Any attempt to read object data which exceeds the boundaries of the custom data written by the corresponding writeObject method will cause an OptionalDataException to be thrown with an eof field value of true. Non-object reads which exceed the end of the allotted data will reflect the end of data in the same way that they would indicate the end of the stream: bytewise reads will return -1 as the byte read or number of bytes read, and primitive reads will throw EOFExceptions. If there is no corresponding writeObject method, then the end of default serialized data marks the end of the allotted data.

So, the best idea would be to catch an OptionalDataException and check it's eof field for true.

And to digest the answer even further, here's the method you want:

TransactionRecord readRecord(ObjectInputStream stream) throws OptionalDataException, IOException {
    try {
        transactionRecord = (TransactionRecord) stream.readObject();
    } catch (OptionalDataException e) {
        if (e.eof) {
            return null;
        } else {
            throw e;
        }
    }
    return transactionRecord;
}
.....
TransactionRecord record;
while ((record = readRecord(inTrans)) != null) {
    doSomethingWithRecord(record);
}
endOfFile();
Sign up to request clarification or add additional context in comments.

Comments

1

Yes, check the input stream to see if anything more is available:

http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html#available()

if (inOldmast.available() > 0) {
  // read and process
} else {
  // Close the stream and clean up
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.