So - I've got a third party library that needs a File as input. I've got a byte array.
I don't want to write the bytes to disk .. I'd like to keep this in memory. Any idea on how I can create a File from the provided byte array (without writing to disk)?
Sorry, not possible. A File is inherently an on-disk entity, unless you have a RAM disk - but that's not something you can create in Java.
That's exactly the reason why APIs should not be based on File objects (or be overloaded to accept an InputStream).
There's one possibility, but it's a real long-shot.
If the API uses new FileReader(file) or new FileInputStream(file) then you're hosed, but...
If it converts the file to a URL or URI (using toURL() or toURI()) then, since File is not final, you can pass in a subclass of File in which you control the construction of the URL/URI and, more importantly, the handler.
But the chances are VERY slim!
So I see there is an accepted answer (and this is old), but I found a way to do this. I was using the IDOL On Demand API and needed to convert a byte array to a File.
Here is an example of taking a byte array of an image and turning into a File:
//imageByte is the byte array that is already defined
BufferedImage image = null;
ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
image = ImageIO.read(bis);
bis.close();
// write the image to a file
File outputfile = new File("image.png");
ImageIO.write(image, "png", outputfile);
And so outputfile is a File that can be used later in your program.
Related
I already have a GZIPOutput stream which has already defined. Now I want to convert it to a byte array.
I tried the code below. But it gives an error.
GZIPOutputStream zipStream = createGZIP();
byte[] compressedData = zipStream.toByteArray();
error : cannot resolve method "toByteArray()"
checked GZIP compression to a byte array , but it is inputting a byte[]. I need to convert a gzip which I already have.
I have a GZIPOutput stream which has already defined. Now I want to convert it to a byte array.
You will need to modify the method that is creating the GZIPOutputStream so that it sends it to a ByteArrayOutputStream.
Alternatively, after closing the FileOutputStream for the file where you are (presumably) writing the compressed data, open it for input and read it into a byte array.
Concerning your current attempt:
GZIPOutputStream zipStream = createGZIP();
byte[] compressedData = zipStream.toByteArray();
This approach is not going to work.
GZIPOutputStream provides no API methods for retrieving the compressed data.
GZIPOutputStream provides no API methods for retrieving the stream that GZIPOutputStream is writing to. (And even if there was, most OutputStream types don't allow you to retrieve the data ...)
In general, it is better to find and read the javadocs for the classes that you use. Programming by guessing what methods they provide is liable to lead you to waste your time when your guess are wrong.
as the title say i need to find some java jpeg encoder (it's good both source code or external library) that given an array that represent a raw pixel image or a BufferedImage can encode it without writing anything on file and return the encoded image possibly trough an array of some kind, with at least possibility to choose image quality and possibly with good efficiency.
NB: the array/image type input required (byte, int, argb, rgb, bgr, yuv...) doesn't matter for me, i can make approppriate conversions
As already mentioned in the comments: You can use the ImageIO class, and use it to write to a ByteArrayOutputStream. The code could really be as simple as this:
private static byte[] getJpgData(BufferedImage image)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", baos);
return baos.toByteArray();
}
This will NOT write the image to a disc or so. It will only write the image into a memory block, which you can then process or manipulate further.
If you just need a stream of bytes, then use Java's built in methods.
http://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html#write(java.awt.image.RenderedImage,%20java.lang.String,%20java.io.OutputStream)
ImageIO.write(myImage, "format", myOutputStream);
I have a binary file that contains big endian data. I am using this code to read it in
FileChannel fileInputChannel = new FileInputStream(fileInput).getChannel();
ByteBuffer bb = ByteBuffer.allocateDirect((int)fileInputChannel.size());
while (bb.remaining() > 0)
fileInputChannel.read(bb);
fileInputChannel.close();
bb.flip();
I have to do something identical for zip files. In other words decompress the file from a zip file and order it. I understand I can read it in via ZipInputStream but then I have to provide the coding for the "endianness". With ByteBuffer you can use ByteOrder.
Is there an NIO alternative for zip files ?
If you have your ZipInputStream, just use Channels.newChannel to convert it to a Channel then proceed as you wish. But you should keep in mind that it might be possible that a ZipInputStream can’t predict its uncompressed size so you might have to guess the appropriate buffer size and possibly re-allocate a bigger buffer when needed. And, since the underlying API uses byte arrays, there is no benefit in using direct ByteBuffers in the case of ZipInputStream, i.e. I recommend using ByteBuffer.allocate instead of ByteBuffer.allocateDirect for this use case.
By the way you can replace while(bb.remaining() > 0) with while(bb.hasRemaining()). And since Java 7 you can use FileChannel.open to open a FileChannel without the detour via FileInputStream.
Does
final OutputStream output = new FileOutputStream(file);
truncate the file if it already exists? Surprisingly, the API documentation for Java 6 does not say. Nor does the API documentation for Java 7. The specification for the language itself has nothing to say about the semantics of the FileOutputStream class.
I am aware that
final OutputStream output = new FileOutputStream(file, true);
causes appending to the file. But appending and truncating are not the only possibilities. If you write 100 bytes into a 1000 byte file, one possibility is that the final 900 bytes are left as they were.
FileOutputStream without the append option does truncate the file.
Note that FileOutputStream opens a Stream, not a random access file, so i guess it does make sense that it behaves that way, although i agree that the documentation could be more explicit about it.
I tried this on Windows 2008 x86 and java 1.6.0_32-b05
I created 2 processes which wrote continually to the same file one 1Mb of the character 'b' and the other 4Mb of the character 'a'. Unless I used
out = new RandomAccessFile(which, "rw");
out.setLength(0);
out.getChannel().lock();
I found that a 3rd reader process could read what appeared to be a File which started with 1Mb of 'b's followed by 'a's
I found that writing first to a temporary file and then renaming it
File.renameTo
to the File also worked.
I would not depend on FileOuputStream on windows to truncate a file which may be being read by a second process...
Not new FileOutputStream(file)
Nor FileOutputStream(file, false) ( does not truncate )
Nor
this;
out = new FileOutputStream(which, false);
out.getChannel().truncate(0);
out.getChannel().force(true);
However
out = new FileOutputStream(which, false);
out.getChannel().truncate(0);
out.getChannel().force(true);
out.getChannel().lock();
does work
FileOutputStream is meant to write binary data, which is most often overwritten.
If you are manipulating text data, you should better use a FileWriter which has convenient append methods.
In Java you have to do
new ZipFile(new File("xxx.zip"));
to unzip a zip file.
Now I get a byte array whose content is a zip file. I get this byte array from database instead of a file. I would like to unzip this "byte array file" but there is no ZipFile constructor for byte array or String (I mean the content instead of the file path).
Is there any solution? (Of course I do not want to write this byte array to an actual file and read it into memory again.)
Thanks!
Use a ByteArrayInputStream inside the ZipInputStream which is created from a byte array
byte[] ba;
InputStream is = new ByteArrayInputStream(ba);
InputStream zis = new ZipInputStream(is);
Use zis to read the contents uncompressed
Implementations of ZipFile requires it to be a file. Memory mapping may be used, for instance. In general it is assumed that the archive may be huge.
As #Perception mentions, ZipInputStream can be used to read sequentially through the stream. Third-party libraries may be available to replace ZipFile.