37

I am reading dds textures, but since once built the jar I can't access those textures through url and file and have to use InputStream instead.

So I would need to know how I can obtain a java.​nio.ByteBuffer from an java.io.InputStream.

Ps: no matter through 3rd part libraries, I just need it working

0

4 Answers 4

53

For me the best in this case is Apache commons-io to handle this and similar tasks.

The IOUtils type has a static method to read an InputStream and return a byte[].

InputStream is;
byte[] bytes = IOUtils.toByteArray(is);

Internally this creates a ByteArrayOutputStream and copies the bytes to the output, then calls toByteArray().

UPDATE: as long as you have the byte array, as @Peter pointed, you have to convert to ByteBuffer

ByteBuffer.wrap(bytes)

JAVA 9 UPDATE: as stated by @saka1029 if you're using java 9+ you can use the default InputStream API which now includes InputStream::readAllBytes function, so no external libraries needed

InputStream is;
byte[] bytes = is.readAllBytes()
Sign up to request clarification or add additional context in comments.

4 Comments

and then to ByteBuffer?
@elect yes, ByteBuffer.wrap(bytes)
it may OutOfMemory
@chen it may OOM. This method is for small files only. That's why people invented InputStream API :-) >> to read something as a stream (some piece after piece).
5

What is about:

ReadableByteChannel channel = Channels.newChannel(inputStream);
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);

while (channel.read(buffer) != -1) {
  //write buffer

};

6 Comments

Are you sure that read() returns -1 when input stream ends? Sometimes it returns 0.
Yes, I am %)) this is from javadoc from ReadableByteChannel Returns: The number of bytes read, possibly zero, or -1 if the channel has reached end-of-stream
If the buffer isn't big enough to read the entire input stream this can get stuck in a busy loop trying to read 0 bytes over and over. Depending on how the body of the loop deals with the buffer. e.g. if you just want to read everything into a buffer and return the buffer, so the buffer won't be emptied or flipped in the loop.
@happy_marmoset It returns -1 at end of stream, and 0 if the buffer is full or if you are reading from a non-ready non-blocking SocketChannel.
@swpalmer That's what compact() is for.
|
3

A neat solution with no 3rd party library needed is

ByteBuffer byteBuffer = ByteBuffer.allocate(inputStream.available());
Channels.newChannel(inputStream).read(byteBuffer);

See ReadableByteChannel#read(ByteBuffer)

3 Comments

Are you sure that one read() is enough to read all input stream?
No, it depends on the InputStream you are using. If it has all the bytes available then it will work.
This is not a correct use of InputStream.available(), and the Javadoc specifically says so. It does not return the total number of bytes in the stream, and may return zero.
2

From Java 9, there is method readAllBytes (in class java.io.InputStream) that returns a byte array. You pass that byte array to [static] method wrap (in class java.nio.ByteBuffer), for example:

public ByteBuffer fromInputStrem(InputStream is) throws IOException {
    return ByteBuffer.wrap(is.readAllBytes());
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.