Read-only view of ByteArrayInputStream content
Archie Cobbs
archie.cobbs at gmail.com
Tue Jul 9 16:17:35 UTC 2024
On Tue, Jul 9, 2024 at 10:51 AM Martin Desruisseaux <
martin.desruisseaux at geomatys.com> wrote:
> JDK-22 has modified ByteArrayInputStream.transferTo(OutputStream)
> implementation for performing a defensive copy of the byte array when the
> destination is not trusted (JDK-8321053). However, I was using the previous
> implementation as a trick for reading the array without copy. The reason is
> because we have millions of ByteArrayInputStream instances when reading
> BLOBs from a database (e.g., geometries from a spatial database), and some
> popular JDBC drivers implement ResultSet.getBinaryStream(int) by reading
> all data in a byte[] array and wrapping the array in a
> ByteArrayInputStream. As a cleaner replacement for my old trick, would it
> be possible to add something like the following method in
> ByteArrayInputStream?
>
> /**
> * Returns the remaining content of this input stream as a read-only buffer.
> * The sequence of remaining bytes in the buffer is the same as the sequence
> * of bytes that would be returned by {@link #readAllBytes()}.
> *
> * @return the remaining content of this input stream, as a read-only buffer
> */
> public synchronized ByteBuffer asByteBuffer() {
> return ByteBuffer.wrap(buf, pos, count - pos).slice().asReadOnlyBuffer();
> }
>
> The call to slice() is for blocking callers from accessing the bytes
> before the current stream position. I assumed that it could be a security
> issue. If this proposal is acceptable, I can create a pull request.
>
A few random thoughts...
First, let's consider what you are optimizing for. The difference in the
old vs. new behavior is the use of a 128k temporary transfer buffer. So if
I understand this correctly the performance problem you are addressing (in
terms of blown cache) is not proportional to the size of the original BLOB,
but to at most 128K (in both the old and new cases, you have to scan the
entire BLOB, so that's a wash). Does that 128K create a noticeable
difference?
Anyway, IMHO more interoperability between the different Java "ways of
doing things" is good. E.g., converting between Instant and Date, etc. This
falls into that category. In fact, in the past I've wished for the reverse
- i.e., ByteBuffer.asOutputStream() - and ended up creating a simple
wrapper class that does that. So perhaps these two additions could go
together - just a thought.
Minor nit - the Javadoc would need to clarify that operations on the
returned ByteBuffer have no effect on the original OutputStream.
-Archie
--
Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240709/ec8ade50/attachment.htm>
More information about the core-libs-dev
mailing list