LJWolfe
LJWolfe

Reputation: 43

Using Dynamic Buffers? Java

In Java, I have a method

public int getNextFrame( byte[] buff )

that reads from a file into the buffer and returns the number of bytes read. I am reading from .MJPEG that has a 5byte value, say "07939", followed by that many bytes for the jpeg.

The problem is that the JPEG byte size could overflow the buffer. I cannot seem to find a neat solution for the allocation. My goal is to not create a new buffer for every image. I tried a direct ByteBuffer so I could use its array() method to get direct access to the underlying buffer. The ByteBuffer does not expand dynamically.

Should I be returning a reference to the parameter? Like:

public ByteBuffer getNextFrame( ByteBuffer ref )

How do I find the bytes read? Thanks.

Upvotes: 4

Views: 6455

Answers (4)

Peter Lawrey
Peter Lawrey

Reputation: 533820

EDIT:

Allocating a byte[] is so much faster than reading from a file or a socket, I would be surprised it will make much difference, unless you have a system where micro-seconds cost money.

The time it takes to read a file of 64 KB is about 10 ms (unless the file is in memory)

The time it takes to allocate a 64 KB byte[] is about 0.001 ms, possibly faster.


You can use apache IO's IOBuffer, however this expands very expensively.

You can also use ByteBuffer, the position() will tell you how much data was read.

If you don't know how big the buffer will be and you have a 64-bit JVM you can create a large direct buffer. This will only allocate memory (by page) when used. The upshot is that you can allocate a 1 GB but might only ever use 4 KB if that is all you need. Direct buffer doesn't support array() however, you would have to read from the ByteBuffer using its other methods.

Another solution is to use an AtomicReference<byte[]> the called method can increase the size as required, but if its large enough it would reuse the previous buffer.

Upvotes: 0

Daniel
Daniel

Reputation: 28104

Just read the required number of bytes. Do not use read(buffer), but use read(buffer,0,size). If there are more bytes, just discard them, the JPG is broken anyway.

Upvotes: 1

Boris
Boris

Reputation: 4537

java.io.ByteArrayOutputStream is a wrapper around a byte-array and enlarges it as needed. Perhaps this is something you could use.

Edit:
To reuse just call reset() and start over...

Upvotes: 1

mihi
mihi

Reputation: 6735

The usual way of accomplishing this in a high-level API is either let the user provide an OutputStream and fill it with your data (which can be a ByteArrayOutputStream or something completely different), or have an InputStream as return value, that the user can read to get the data (which will dynamically load the correct parts from the file and stop when finished).

Upvotes: -1

Related Questions