Java InputStream to ByteBuffer - java

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

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()

What is about:
ReadableByteChannel channel = Channels.newChannel(inputStream);
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
while (channel.read(buffer) != -1) {
//write buffer
};

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)

Related

Turning an InputStream into a SeekableByteChannel

I am attempting to convert an InputStream to a SeekableByteChannel in order to stream in Open AL with LWJGL.
The current code is as follows thanks to the help of a demo online:
InputStream source = Thread.currentThread().
getContextClassLoader().
getResourceAsStream(resource);
ReadableByteChannel rbc = Channels.newChannel(source);
But I'm not sure, if at all possible, how I can seek through the OGG file in order to stream without converting it to a SeekableByteChannel
I'd be glad to supply more code if needed and thanks for any help in advance
Take a look at apache commons compress library, you can construct a SeekableInMemoryByteChannel from byte array. And convert InputStream to byte array is very easy also.
InputStream inputStream; // input stream
SeekableInMemoryByteChannel channel = new SeekableInMemoryByteChannel
(IOUtils.toByteArray(inputStream));

Java - Resetting InputStream

I'm dealing with some Java code in which there's an InputStream that I read one time and then I need to read it once again in the same method.
The problem is that I need to reset it's position to the start in order to read it twice.
I've found a hack-ish solution to the problem:
is.mark(Integer.MAX_VALUE);
//Read the InputStream is fully
// { ... }
try
{
is.reset();
}
catch (IOException e)
{
e.printStackTrace();
}
Does this solution lead to some unespected behaviours? Or it will work in it's dumbness?
As written, you have no guarantees, because mark() is not required to report whether it was successful. To get a guarantee, you must first call markSupported(), and it must return true.
Also as written, the specified read limit is very dangerous. If you happen to be using a stream that buffers in-memory, it will potentially allocate a 2GB buffer. On the other hand, if you happen to be using a FileInputStream, you're fine.
A better approach is to use a BufferedInputStream with an explicit buffer.
It depends on the InputStream implementation. You can also think whether it will be better if you use byte[]. The easiest way is to use Apache commons-io:
byte[] bytes = IOUtils.toByteArray(inputSream);
You can't do this reliably; some InputStreams (such as ones connected to terminals or sockets) don't support mark and reset (see markSupported). If you really have to traverse the data twice, you need to read it into your own buffer.
Instead of trying to reset the InputStream load it into a buffer like a StringBuilder or if it's a binary data stream a ByteArrayOutputStream. You can then process the buffer within the method as many times as you want.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int read = 0;
byte[] buff = new byte[1024];
while ((read = inStream.read(buff)) != -1) {
bos.write(buff, 0, read);
}
byte[] streamData = bos.toByteArray();
For me, the easiest solution was to pass the object from which the InputStream could be obtained, and just obtain it again. In my case, it was from a ContentResolver.

Write byte array to ZipArchiveOutputStream

I need to create a zip file and am limited by the following conditions:
The entries come as byte[] (or ByteArrayOutputStream) and not as File.
The filenames for the entry can be non-ascii/UTF-8.
JDK 1.6 or earlier
Since java.util.zip only supports UTF-8 filenames from JDK 1.7 and onward, it seems better to use commons-compress ZipArchiveOutputStream. But how to create a ZipEntryArchive based on a byte array or ByteArrayOutputStream rather than a File?
Thank you!
The following method takes a byte[] as input, produces a zip and returns its content as another byte[]. All is done in memory. No IO operations on the disk. I stripped exception handling for a better overview.
byte[] zip(byte[] data, String filename) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipArchiveOutputStream zos = new ZipArchiveOutputStream(bos);
ZipArchiveEntry entry = new ZipArchiveEntry(filename);
entry.setSize(data.length);
zos.putArchiveEntry(entry);
zos.write(data);
zos.closeArchiveEntry();
zos.close();
bos.close();
return bos.toByteArray();
}
Does this solve your problem?

Write and read byte[] from file

I'm looking for something simple (no external lib preferably) to write and load a byte[] from a file. More or less something like [Python's pickle][1].
byte[] bytes = new byte[10];
ByteBuffer bbuf = new ByteBuffer.allocate(bytes.length);
bbuf.wrap(bytes); // edited due to Jon Skeet's answer
CharBuffer cbuf = bbuf.asCharBuffer();
cbuf.put("t");
FileOutputStream test = new FileOutputStream("somebytes");
test.write(bytes);
test.close();
The problem seems to be that I cannot read the Object structure from a file like that. In a hex-editor furthermore the file "somebytes" contains just a couple or 0s. So it doesn't seem the FileOutputStream puts any of the content ("t" or the byte-equivalent) into it.
[1] http://wiki.python.org/moin/UsingPickle
You've allocated a byte buffer with the size of bytes, but that doesn't mean the byte buffer is associated with the byte array. You can wrap a byte array using ByteBuffer.wrap.
Here's a minimal change to your code which does write the t into the file:
byte[] bytes = new byte[10];
ByteBuffer bbuf = ByteBuffer.wrap(bytes);
CharBuffer cbuf = bbuf.asCharBuffer();
cbuf.put("t");
FileOutputStream test = new FileOutputStream("somebytes");
test.write(bytes);
test.close();
Note that for real code you should use a try/finally block to make sure the file is always closed regardless of exceptions.
However, this is a long way from serialization. Java does have its own binary serialization - see ObjectOutputStream and ObjectInputStream. Personally I usually avoid this sort of serialization however, as it can be very brittle in the face of changes to classes. There are various other approaches to serialization, such as using Thrift or Protocol Buffers for binary serialization, or serializing to XML, JSON or some other human-readable format.
You can
seek(position)
b = read(length)
Then b will be an array of bytes of your length.
Sorry - on rereading you're looking for writing, not reading.
A simpler version of the same thing is.
byte[] bytes = new byte[10];
bytes[1] = 't';
FileOutputStream test = new FileOutputStream("somebytes");
test.write(bytes);
test.close();
There are plenty of examples on how to read/write byte[] from files on the web. try google.

Byte[] to InputStream or OutputStream

I have a blob column in my database table, for which I have to use byte[] in my Java program as a mapping and to use this data I have to convert it to InputStream or OutputStream. But I don't know what happens internally when I do so. Can anyone briefly explain me what's happening when I do this conversion?
You create and use byte array I/O streams as follows:
byte[] source = ...;
ByteArrayInputStream bis = new ByteArrayInputStream(source);
// read bytes from bis ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
// write bytes to bos ...
byte[] sink = bos.toByteArray();
Assuming that you are using a JDBC driver that implements the standard JDBC Blob interface (not all do), you can also connect a InputStream or OutputStream to a blob using the getBinaryStream and setBinaryStream methods1, and you can also get and set the bytes directly.
(In general, you should take appropriate steps to handle any exceptions, and close streams. However, closing bis and bos in the example above is unnecessary, since they aren't associated with any external resources; e.g. file descriptors, sockets, database connections.)
1 - The setBinaryStream method is really a getter. Go figure.
I'm assuming you mean that 'use' means read, but what i'll explain for the read case can be basically reversed for the write case.
so you end up with a byte[]. this could represent any kind of data which may need special types of conversions (character, encrypted, etc). let's pretend you want to write this data as is to a file.
firstly you could create a ByteArrayInputStream which is basically a mechanism to supply the bytes to something in sequence.
then you could create a FileOutputStream for the file you want to create. there are many types of InputStreams and OutputStreams for different data sources and destinations.
lastly you would write the InputStream to the OutputStream. in this case, the array of bytes would be sent in sequence to the FileOutputStream for writing. For this i recommend using IOUtils
byte[] bytes = ...;//
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
FileOutputStream out = new FileOutputStream(new File(...));
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
and in reverse
FileInputStream in = new FileInputStream(new File(...));
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
byte[] bytes = out.toByteArray();
if you use the above code snippets you'll need to handle exceptions and i recommend you do the 'closes' in a finally block.
we can convert byte[] array into input stream by using ByteArrayInputStream
String str = "Welcome to awesome Java World";
byte[] content = str.getBytes();
int size = content.length;
InputStream is = null;
byte[] b = new byte[size];
is = new ByteArrayInputStream(content);
For full example please check here http://www.onlinecodegeek.com/2015/09/how-to-convert-byte-into-inputstream.html
There is no conversion between InputStream/OutputStream and the bytes they are working with. They are made for binary data, and just read (or write) the bytes one by one as is.
A conversion needs to happen when you want to go from byte to char. Then you need to convert using a character set. This happens when you make String or Reader from bytes, which are made for character data.
output = new ByteArrayOutputStream();
...
input = new ByteArrayInputStream( output.toByteArray() )
I do realize that my answer is way late for this question but I think the community would like a newer approach to this issue.
byte[] data = dbEntity.getBlobData();
response.getOutputStream().write();
I think this is better since you already have an existing OutputStream in the response object.
no need to create a new OutputStream.

Categories

Resources