0

无论如何要检查 ObjectInputStream 类的方法 readObject 是否已完成读取文件而不是捕获其抛出的异常?

如果没有。我怎样才能弄出Newmast.writeObject(accountRecord); 在这种情况下达成的声明?

// 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
4

2 回答 2

2

最好的主意是预先序列化元素的数量,所以你可以这样做:

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

如文档中所述,@ChrisCooper 提出的方法不可靠。有些流没有实现它,或者返回近似结果(理论上,当还有一些数据时它甚至可以返回 0。示例 - 网络流)。

因此,查看相同的文档,我们发现了这个特定的块:

任何超出相应 writeObject 方法写入的自定义数据边界的对象数据的读取尝试都将导致抛出 OptionalDataException,并且 eof 字段值为 true。超出分配数据结尾的非对象读取将反映数据的结尾,就像它们指示流的结尾一样:按字节读取将返回 -1 作为字节读取或读取的字节数,以及原始读取将抛出 EOFExceptions。如果没有对应的 writeObject 方法,则默认序列化数据的结尾标志着分配数据的结尾。

所以,最好的办法是捕获一个OptionalDataException并检查它的eof字段true

为了进一步消化答案,这是您想要的方法:

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();
于 2013-03-05T11:59:47.883 回答
1

是的,检查输入流以查看是否有更多可用的内容:

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
}
于 2013-03-05T11:56:44.900 回答