Java 7 introduced a zip FileSystem. The link below illustrates how to create a zip FileSystem from a zip file.
http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html
However, I can find no example of how to create a zip FileSystem from an InputStream. Is that possible? If so, how?
Note: I know I can write the InputStream to disk and create a zip FileSystem as described. I consider that a hack, and I would prefer to avoid it.
No, it's not possible because the file system requires random access to the ZIP file.
Shameless self-plug: You may find TrueZIP easier to work with and more powerful. However, the same constraint applies to it, too.
Only a partial answer, but I expect you'll need a custom file system provider and this question about an in-memory file system might help. Note that the newFileSystem documentation shows a memory://... URL scheme, but no more detail.
As pointed out in another answer, the file system requires bidirectional access to the data, so this assumes enough memory to load it entirely.
Related
I would like to use a Java library in my Android application. The class constructors and methods of this library often take paths to files (configuration file, dictionary, etc.) and then build java.io.file instances based on the given paths.
In my android application, I would like to store these file in the 'res' folder (possibly in res/raw). The problem is that I have to give a path to these files to the methods of the library.
I could easily get an InputStream using getResources(), but this would not be directly usable by my library. I would have to go through all the methods taking a path as an argument, replace it by an InputStream and modify the content to deal with InputStreams instead of Files. This represent quite a lot of work and I would much prefer to use the library without modification and keep it easily upgradable.
Even though using java.io.file based on resource file would not be a good practice, is it something possible? It would definitely help if you could indicate a way to do this.
Thank you.
If the library uses java.io.File then I don't think there is a way to do this in Java (let alone the Android subset of Java). It might be possible to solve the problem with a loopback filesystem, but this depends on your Android device's kernel, etc.
See:
https://android.stackexchange.com/questions/25396/how-to-find-out-if-my-devices-kernel-has-loop-device-support
If the library uses java.nio.file.Path, then it may be possible to implement a custom FileSystemProvider that maps the resources into the default file system namespace.
Note this is for regular Java 7. It would require a back-port of the relevant NIO libraries to get this to work on Android. I had another look for a viable backport, and couldn't find one.
See:
Tweaking the behavior of the default file system in Java 7
How to use java.nio.file package in android?
There is another "clunky" way to do this. Get your application to copy the relevant resources to files that can be accessed via a File.
I want to create a simple in-memory file system in Java, which has one root directory and is able to make new sub directory. In the directory we can make new files, write in them, read from them, delete them and also rename them. Can you please give some advice from where to start (a simple code, or resouce).
A custom file system provider must implement the java.nio.file.spi.FileSystemProvider class. A file system provider is identified by a URI scheme such as file, jar, memory, cd.
These links below provide good starting info
http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/filesystemprovider.html
The link below(not about in memory file system) is about virtual file system. It talks about some design issues which could help you in case you decide to create your own file system.
http://www.flipcode.com/archives/Programming_a_Virtual_File_System-Part_I.shtml
But you could always use already built and tested code.This will be faster and easier to maintain and you will receive support in error conditions.
Take a look at jimfs ( An in-memory file system for Java 7+ )
https://github.com/google/jimfs
Also look into
Commons Virtual File System
http://commons.apache.org/proper/commons-vfs/
marschall (An in memory implementation of a JSR-203 file system)
https://github.com/marschall/memoryfilesystem
You can create In-memory file system in java using Google’s Jimfs and java 7 NIO package.
Please refer this link. Here you will get a sample tutorial:
create In-memory file system in java
Use memoryfilesystem.
Jimfs has been mentioned in a previous answer, but memoryfilesystem handles much more.
Example usage:
final FileSystem fs = MemoryFileSystem.newLinux().build("myfs");
final Path dir = fs.getPath("thedir");
Files.createDirectory(dir);
etc etc. Use the java.nio.file API to manipulate files in this (File won't work!). See here for more details.
My Java application is currently using ZIP as a project file format. The project files contain a few XML files and many image and sound files.
The project files are getting pretty big, and since I can't find a way with the java.util.zip classes to write to a ZIP file without recreating it, my file saves are becoming very slow. So for example, if I just want to update one XML file, I need to rewrite the entire ZIP.
Is there some other Java ZIP library that will allow me to do random writes to a ZIP file?
I know switching to something like SQLite solves the random write issue. Would using SQLite just to write XML, Sound and Images as blobs be an appropriate use?
I suppose I could come up with my own file format and use RandomAccessFile but then there would be a lot of bookkeeping I'd have to write.
Update...
My file format is very much like Office Open XML. It is a ZIP file containing XML and other resources.
Someone must have solved the problem of how to do random writes to update a ZIP file. Does anyone know how?
There exist so-called single-file virtual file systems, that let you create file-based containers and provide file-system like structure and APIs. One of the samples is SolFS (it has C-written core with JNI wrapper) and some other C- and Delphi-written solutions (I don't remember their names at the moment). I guess there exist similar native Java solutions as well.
First of all I would separate your app's resources in those that are static (such as images) and those that can be changed (the xml files you mentioned).
Since the static files won't be re-written, you can continue to store them in a zip file, which IMHO is a good approach to deploy any resources.
Now you have 2 options:
Since the non-static files are probably not too big (the xml files are likely to be smaller than images+sounds), you can stick with your current solution (zip file) and simply maintain 2 zip files, of which only one (the smaller one with the changeable files) can/will be re-written.
You could use a in-memory-database (such as hsqldb) to store the changeable files and only persist them (transferring from the database to a file on the drive) when your application shuts down or that operation is explicitly needed.
sqlite is not always fast (at least in my experience). I would suggest individually compressing the XML files -- you'll still get decent compression, and just use the file system to save them. You could experiment with btrfs, or just go with ext4. If you're not on Linux, then this should still work okay, but it might not be as fast until things are cached in memory.
the idea is that if you do not have redundancy between XML files, then you don't get that much saving by compressing them in one "solid" archive.
Before offering another answer along the lines of using properly structured JARs, I have to ask -- why does the project need to be encapsulated in one file? How do you distribute the program to users to run?
If you must keep a project contained within a single file and be able to replace resources efficiently, yes I would say SQLite is a good choice.
If you do choose to use SQLite, also consider converting some of the XML schemas to one or more SQL tables rather than storing large XML documents as BLOBs.
The class java.io.FileReader not found in Java ME.
I need this in order to get the file and then parse it with an xml parser.
Anyone know any alternatives for this class?
*added
using CLDC profile. The xml file to be read is in the JAR.
That's because Java ME provides only a limited subset of the java.io package. You need to use the java.microedition.io package instead.
For actual file I/O you'll need to use the FileConnection class provided by JSR-75.
What Java ME profile are you using? The CLDC does not support the concept of files at all.
In general, FileReader is nothing but a convenience class that wraps an InputStreamReader areound a FileInputStream. It's also very broken because it does not allow specifying the encoding, and should therefore almost never be used.
It would be especially wrong to use it to read XML because proper XML data specifies its encoding, and a proper XML parser will handle that, so you really should pass binary data to the XML parser.
So if you're on the CDC profile, just use a FileInputStream directly.
the question is a bit ambiguous. I think Joachim's answer might be only partial if you are trying to read a local file. I'm certainly not sure though.
If the file is stored as a resource in your JAR, you can access it through the getResourceAsStream method in Class.
If the file is a local file on the file system and if I recall correctly, you need JSR-75 support. Over at Sun's developer page there is an introduction to JSR 75 and the fileconnection
API.
I have a JAR file that contains an API that uses external model files. I would like to include the model files in the JAR itself so it easier to use for other developers. The API will accept a File object only, is there any way to do this? I have already tried the following, and they have failed:
Using class.getResourceAsStream(). This would work if the API accepted an InputStream.
Parsing the classpath and trying to build from the entries (the JAR will show as app.jar)
I suppose an option is to use getResourceAsStream and move the files to a permanent location on the HDD but, I do not like this option. There has to be something better, any thoughts?
Resources in a .jar file are not files in the sense that the OS can access them directly via normal file access APIs.
And since java.io.File represents exactly that kind of file (i.e. a thing that looks like a file to the OS), it can't be used to refer to anything in a .jar file.
A possible workaround is to extract the resource to a temporary file and refer to that with a File.
Note that generally APIs that try to handle files should be written to handle InputStream/OutputStream as well to allow this kind of operations to suceed.