我有以下一组代码来将业务对象写入文件。写作通常分两部分完成,但writeTrx
- 助手在这里同时进行临时文件写入和重命名:
public static void writeTrx(File dbDir, Trx trx, String idString) throws IOException {
UnfinishedTrx temp = writeTempTrxFile(dbDir, trx, idString);
finishWritingTrx(temp);
}
public static UnfinishedTrx writeTempTrxFile(File dbDir, Trx trx, String idString) throws IOException {
File tempDir = getAndCreateTempDir(dbDir);
Path tempFilePath = Files.createTempFile(tempDir.toPath(), idString, ".tmp_trx");
try (OutputStream fos = Files.newOutputStream(tempFilePath)) {
writeTrx(fos, trx);
}
return new UnfinishedTrx(dbDir, idString, tempFilePath);
}
public static void writeTrx(OutputStream out, Trx trx) throws IOException {
try (BufferedOutputStream bos = new BufferedOutputStream(out);
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
oos.writeObject(trx);
}
}
然而,我确实从java.nio.channels.ClosedChannelException
获得了这个:
at sun.nio.ch.FileChannelImpl.ensureOpen(FileChannelImpl.java:99)
at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:192)
at java.nio.channels.Channels.writeFullyImpl(Channels.java:78)
at java.nio.channels.Channels.writeFully(Channels.java:101)
at java.nio.channels.Channels.access$000(Channels.java:61)
at java.nio.channels.Channels$1.write(Channels.java:174)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:126)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1876)
at java.io.ObjectOutputStream$BlockDataOutputStream.writeByte(ObjectOutputStream.java:1914)
at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1575)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:350)
at foo.TrxHelper.writeTrx(TrxHelper.java:125)
at foo.TrxHelper.writeTempTrxFile(TrxHelper.java:99)
at foo.TrxHelper.writeTrx(TrxHelper.java:91)
这让我感到困惑。如何通过ObjectOutputStream这样的调用结构关闭通道,在调用close时关闭流 ?
我的理解是,当内部writeTrx调用返回时,流应该最早关闭,而不是在其中。