While we can think about shorter term ways to improve bfconvert, raw2ometiff, etc., I think ultimately we'll want to modernize some of the writing implementations here. Some specific ideas:
Allow setting an initial file length for writable handles/streams. In the file conversion use cases, we know the size of the uncompressed pixel data being written, and can estimate an initial length based on the compression type used.
Buffer writes, similar to what RandomAccessInputStream does for reads. Things like NIOFileHandle.writeInt already create a ByteBuffer, store the int in the ByteBuffer, and then write out the ByteBuffer; switching that to use a reusable ByteBuffer of configurable size should be straightforward.
Possibly better file length handling on close. Calls to setLength are pretty specific to what's being written, so that the length is typically not larger than what actually gets written. close() methods don't currently do anything to fix the length, e.g.:
Open an existing file for writing. The size on disk was 100 bytes.
Set the length to 250 bytes, anticipating 150 bytes of writes before close().
Write 110 bytes (40 anticipated bytes not written due to incorrect estimation of compression ratio).
Call close() - should the length remain 250 bytes as now, or be reset to 210?
In looking briefly at https://github.com/glencoesoftware/raw2ometiff/issues/104 and https://github.com/ome/bioformats/issues/3983, in both cases repeated calls to
NIOFileHandle.setLength
cause a significant slowdown. Looking more closely at how writing is implemented in NIOFileHandle and RandomAccessOutputStream, it appears that there is effectively no write buffering happening.While we can think about shorter term ways to improve bfconvert, raw2ometiff, etc., I think ultimately we'll want to modernize some of the writing implementations here. Some specific ideas:
RandomAccessInputStream
does for reads. Things likeNIOFileHandle.writeInt
already create aByteBuffer
, store theint
in theByteBuffer
, and then write out theByteBuffer
; switching that to use a reusableByteBuffer
of configurable size should be straightforward.setLength
are pretty specific to what's being written, so that the length is typically not larger than what actually gets written.close()
methods don't currently do anything to fix the length, e.g.:close()
.close()
- should the length remain 250 bytes as now, or be reset to 210?