Search code examples
javaexceptionobjectinputstream

ReadObject Method


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

Solution

  • 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();