I am creating POIFSFileSystem instances in various ways, depending on what I have available: a File, FileChannel or InputStream. I just found out that calling POIFSFileSystem.close() (via a try-with-resources) also closes the FileChannel, even when that channel is passed to it from an external source. Any subsequent operations on that channel (like calculating an MD5 hash) then run into a ClosedChannelException. IMHO POIFSFileSystem/FileBackedDataSource should only close the FileChannel if it has created it itself. It would be great if you could fix this.
Hi Arjohn, I'm not sure this is an easy change and the code has been like this for a long time - so there are risks that people rely on the behaviour as it is. You might be able to wrap your FileChannel with a wrapper that delegates all calls to the wrapped channel but the wrapper could have a no-op close(). If you feel strongly about this issue, maybe you could submit a patch. If so, I would recommend adding a new constructor to FileBackedDataSource that takes a flag that says not to close the FileChannel (or a set method).
Hi PJ, I have tried the wrapper approach, but unfortunately the close() method is declared "final" in superclass AbstractInterruptibleChannel. Maybe a third constructor variant for FileChannel would be an option? E.g.: new POIFSFileSystem(FileChannel channel, boolean readOnly, boolean closeChannel)
Yes - a third constructor - that allows the existing constructors to retain their existing behaviours - makes sense.
Do you want me to supply a patch for this? Looks pretty simple to add.
Feel free to submit a patch.
Created attachment 37322 [details] Patch for POIFS ticket 64542
Thanks for the patch but could you add a unit test?
added in POI 5.1.0
Great, thank you.