Turning an InputStream into a SeekableByteChannel - java

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

Related

InputStream to GZIPInputStream, and I need to know the size of the GZIPInputStream

I have a MultipartFile and I need to compress inputStream as gzip and sent it, but I need to find a way to compress it and know the compressed size of it
param: MultipartFile file
try(var inputStream = file.getInputStream()) {
var outputStream = new GZIPOutputStream(OutputStream.nullOutputStream());
IOUtils.copyLarge(inputStream, outputStream);
var compressedInputStream = someConvertMerthod(outputStream);
sendCompressed(compressedInputStream, compressedSize)
}
Maybe I can do something like this Java: How do I convert InputStream to GZIPInputStream? but I am not gonna be a able to get the compressedSize
I am not finding an easy way to do it :(
CopyLarge() returns the number of bytes copied. I would assume this is true even if the output is discarded, so all you need is to capture the return value of IOUtils.copyLarge(in,out) and you should be good to go, but this does assume the return value is bytes WRITTEN and not bytes READ, which is not really documented. So it might work!
In general though, you are assuming you can turn the output stream back into an input stream, so nullOutputStream() is not going to be an option. Instead you will be creating a temp file, writing your compressed data to it, and then closing it. At that point you can simply ask the file system API how big it is, that should be iron clad.
hey I think I found the solution :)
param: MultipartFile file
try (InputStream inputStream = file.getInputStream()) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream);
inputStream.transferTo(gzipOutputStream);
InputStream compressedInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
byteArrayOutputStream.size() // is the compressed size
}
Thanks guys!

Java InputStream to ByteBuffer

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)

equivalent to Files.readAllLines() for InputStream or Reader?

I have a file that I've been reading into a List via the following method:
List<String> doc = java.nio.file.Files.readAllLines(new File("/path/to/src/resources/citylist.csv").toPath(), StandardCharsets.UTF_8);
Is there any nice (single-line) Java 7/8/nio2 way to pull off the same feat with a file that's inside an executable Jar (and presumably, has to be read with an InputStream)? Perhaps a way to open an InputStream via the classloader, then somehow coerce/transform/wrap it into a Path object? Or some new subclass of InputStream or Reader that contains an equivalent to File.readAllLines(...)?
I know I could do it the traditional way in a half page of code, or via some external library... but before I do, I want to make sure that recent releases of Java can't already do it "out of the box".
An InputStream represents a stream of bytes. Those bytes don't necessarily form (text) content that can be read line by line.
If you know that the InputStream can be interpreted as text, you can wrap it in a InputStreamReader and use BufferedReader#lines() to consume it line by line.
try (InputStream resource = Example.class.getResourceAsStream("resource")) {
List<String> doc =
new BufferedReader(new InputStreamReader(resource,
StandardCharsets.UTF_8)).lines().collect(Collectors.toList());
}
You can use Apache Commons IOUtils#readLines:
List<String> doc = IOUtils.readLines(inputStream, StandardCharsets.UTF_8);

Conversion between InputStream and BufferedImage

I want to convert an InputStream object representing an image file to a BufferedImage object and after performing some operations on the BufferedImage convert it back to an InputStream so that it can be written to disk.I dont want to create a file object on disk first in order to prevent additional IO overhead.
I think i can do the following to convert a BufferedImage to InputStream
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image,fileExtension, outputStream);
InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
Is that correct ?. Also, i have the following two questions
How to get BufferedImage object from an InputStream object
Can i get the filesize directly from the InputStream object ?
Some example would really help
Thank You
Take a look at the read(InputStream stream) method of ImageIO
No, you can have a peek using available() but this does not guarantee the size of the stream (it works for FileInputStream)
You can't write to an input stream (as its name states it, it is an input, not an output). To write, you need an OutputStream and you can use the write(RenderedImage im, String formatName, OutputStream output) of ImageIO

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