Viewing images in zip without unzipping - java

I'm working on a Java program that will allow me to view images in a zip/rar file without unzipping it to a folder on my hdd. I'd like to be able to flip through them like on a normal image viewer, possibly able to zoom in/out if needed.
From what I've looked into, it'll have to be extracted even if it's just to a temporary folder, which I'm fine with as long as the program can delete it on its own after. I believe ZipFile would be something I should do more research in? Most of what I've seen deal with text documents rather than image files, so I'm not sure how to proceed in my research.
I'm looking to see if I'm on the right track or if there are any good resources/specific apis I could look into to help as I haven't done any coding in months (save for light php and html) or any java in about a year, and I've had this on the back-burner for long enough.
Thanks in advance. :)

You're on the right track with ZipFile, and I don't think you need to extract to disk before viewing the images.
A ZipFile object will give you a list of its contents with entries(). You can iterate this collection of ZipEntry objects to present a choice of which file to view, and of course filter it to known extensions if you desire.
Strangely enough it's the ZipFile object and not the the individual ZipEntry objects that will give you an InputStream for the given entry. You can read this object into a byte[] in memory and send it to the component that will be responsible for displaying the image.
One caveat is that with zip files, in order to get to the last file stored in the zip it will basically have to decompress the whole archive which can be time consuming. So it may make sense to cache files on disk or an in-memory LRU cache depending on the usage pattern.
You didn't mention if this is for a Swing application, but if it is this might be helpful for displaying the images:
http://docs.oracle.com/javase/tutorial/uiswing/components/icon.html

Related

Reading Unix executable file

I have "Unix Executable file" with no file extension.
In Mac, I am able to see the content in preview mode but not sure about any other way to see the content.
Looking for a way to read the content and store in some other file location as JPG file or PNG file format.
Not sure how to read this thru Java.
In Mac terminal, I tried "file filename" and got the following output.
PNG image data, 110 x 103, 8-bit/color RGB, non-interlaced
Whatever is reporting 'unix executable file' is oversimplifying things. It's simply 'a file' (unix has sod all to do with it), and the file system has the concept of an 'executable' flag, which you can set or clear on any file and is utterly unrelated to whether the file's contents are executable. You can set any file executable, or not, and especially considering that e.g. macs and linux can mount DOS file systems (Which most USB sticks use because every OS can deal with these file systems), which do not have this flag, and 'for convenience' that means the OS acts as if ALL files have that flag and you can't remove it. In other words, it's a lie, forget about that part.
file is just guessing. This is no blame on file and the authors of that tool are by no means lazy. It's mathematically impossible - the disk system doesn't know what kind of data a file contains, it just knows: This file has these bytes, and it ends there. file just looks at the contents and takes a wild stab in the dark. Its wild stabs are decent, but no guarantee. I can make you a file that is BOTH a legal zip file (will unzip and everything just fine), AND is a PNG image equally well (renders in browsers, preview, etc). What could file possibly tell you here? Literally completely random garbage is ALSO a valid ISO-8859-1 formatted text file. The only way to know that this is clearly not the intended purpose of the file is to use Artificial Intelligence algorithms to realize that the contents in no way form legible words in any language on the planet. That's a very hard problem and file doesn't try to solve it.
Thus, there's no real way to know if it is a PNG file, if all you have is a file on disk. The file extension is a good hint, but if it's missing, you're just guessing. You can toss it through a PNG reader, and if it doesn't crash, it probably is, but it could just be a picture with random static because it isn't really a PNG file.
If you want to convert PNG files, ImageIO can do that.
Generally, the process that got you that file usually DOES know the format. For example, if you download it over the web, the web server didn't JUST send those bytes over. It also sent this header: Content-Type: image/png. THAT (and not the file extension) is what is the webserver's canonical truth. If the process that saves this file to disk elected to take that information and toss it in the garbage, well, now you're stuck guessing. If possible, go back to that part of the process and fix it so this info is no longer tossed in the bin. For example, if you have a shell script that uses wget to download a resource and then later on you have no idea if it's a PNG, or a JPG, or the output of a 'file not found' explanatory page in HTML, then fix wget to save that header and react accordingly.

Storing a file in cache rather in hard drive due to user's rights

I'm wondering if I can store a file in cache (or somewhere else), not on the hard drive using JAVA. I got a file as input, copy it to my hard drive now to an another path, modify the copied one and return with it. But what if a user does not have rights to write on hard disk, so the application which uses the file also don't have? Thats why I'm trying to store the copy somewhere else, for example in the cache, is it possible? If yes, is it also possible without any library?
Thanks in advance!
If this is string file, and small enough to fit into memory you can just use:
IOUtils.toString(inputStream, encoding);
for binary file you need to reserve byte array big enough to fit the file content into...

Two applications need to export and import a single file which needs to include data and images, best file type?

I'm making two Java applications one to collect data, another to use it. The one collecting will be importing a file from the other which will include data and images and will be decrypted.
I'm unsure what filetype to use. So far all of the data is in XML and works great but I need the images and was hoping not to have to rely on giving all the images in a folder with a path reference.
Ideas?
well, I think that the best way is to create your own format (.myformat or .data). This file will be in fact a Zip file that contains your XML file and images.
There is no perfect example writen in java as far as I know. However, here are some examples :
Not in java
The best example is, as #Bolo said, the odt format. Indeed, OpenOffice writes the doc in an xml file, and the images too. All that is wrapped in an odt file.
The .exe file is an other example. The C files and the resources are put in a single file. try to open it with 7-zip, you'll see.
The Skyrim plugins are .esp file that contain the dds, the scripts, the niffs (textures)...
In java
The minecraft texture packs are a zip file that contains a .mcmeta file (the infos) and the textures (.png)
Jar files are like exe.
If both programs are in java you could also go with serialization, which is basically saving an object as a file (suffix will be .ser I think) and then being able to retrieve it. You should google it, even if it won't help right now it is quite good to know about it.
I'd suggest using JSON. Gson is a decent library.
You can embed images as byte arrays.
Save the serialized string in a file with a preferred extension, read it from the second application, de-serialize, and reconstruct images.
You can convert binary image data to text with Base64 encoding and this way you can embed your images in XML. [1]: http://en.wikipedia.org/wiki/Base64

Is it possible to merge equally sized mp3 format files, and then retrieve, modify each unit file and add new ones in Java?

Is it possible to merge equally sized mp3 format files, and then retrieve, modify each unit file and add new ones in Java? Is there any tool or programming solution?
MP3 format does not allow clean merging of two files to create a new one without re-encoding. The reason is that first and last frame of the file contain some junk information that has to be discarded. You still can merge the files, like here, but it will not be gapless and accurate. Strip id3v1 tag from the first file (last 120 bytes, if it exists), id3v2 from the second file (see this link to see how to find and get size of id3v2), and then merge the files. Things could get complicated if there are LAME frames. But most player should be able to handle these files.
There is nothing built in to Android to achieve that, because there is no MP3 encoder in the SDK. You'll need an MP3 codec library.
See this answer.
Hope the below link helps you to get what you are looking for
Audacity
http://audacity.sourceforge.net/

How can I protect myself from a zip bomb?

I just read about zip bombs, i.e. zip files that contain very large amount of highly compressible data (00000000000000000...).
When opened they fill the server's disk.
How can I detect a zip file is a zip bomb before unzipping it?
UPDATE Can you tell me how is this done in Python or Java?
Try this in Python:
import zipfile
with zipfile.ZipFile('a_file.zip') as z
print(f'total files size={sum(e.file_size for e in z.infolist())}')
Zip is, erm, an "interesting" format. A robust solution is to stream the data out, and stop when you have had enough. In Java, use ZipInputStream rather than ZipFile. The latter also requires you to store the data in a temporary file, which is also not the greatest of ideas.
Reading over the description on Wikipedia -
Deny any compressed files that contain compressed files.
Use ZipFile.entries() to retrieve a list of files, then ZipEntry.getName() to find the file extension.
Deny any compressed files that contain files over a set size, or the size can not be determined at startup.
While iterating over the files use ZipEntry.getSize() to retrieve the file size.
Don't allow the upload process to write enough data to fill up the disk, ie solve the problem, not just one possible cause of the problem.
Check a zip header first :)
If the ZIP decompressor you use can provide the data on original and compressed size you can use that data. Otherwise start unzipping and monitor the output size - if it grows too much cut it loose.
Make sure you are not using your system drive for temp storage. I am not sure if a virusscanner will check it if it encounters it.
Also you can look at the information inside the zip file and retrieve a list of the content. How to do this depends on the utility used to extract the file, so you need to provide more information here

Categories

Resources