It’s been my geeky dream to use a virtual file system on my next project, for which it’s very likely I will be using Juce. The idea is that other file systems can be ‘embedded’ in the main file system, so that they can be ideally accessed via a standard File() object. Examples for file system types would include zip files, pasteboard contents, music libraries, cloud storage, ftp access etc. Some of these would be quite specific to my own needs, others would be more generally useful (eg. to access assets from the Android APK in the same way as other files, or (maybe in future) to access user documents on Windows 8 Store apps which use a non-standard API).
Here’s one example of an existing library : http://freecode.com/projects/physicsfs. The idea could be taken pretty far (eg. file systems containing other file systems) but a fairly simple API such as this would deliver what I need:
// -------------------- Initialisation -----------------------------
// Mount Android resources to the path '/Assets' in the main filesystem
fileSystem.mount("/Assets", new FileSystemAndroidAPK());
// Mount a zip file to the path '/Archives' in the main filesystem
fileSystem.mount("/Archives", new FileSystemZip("SomeZipFile.zip"));
// Mount Dropbox storage folder, and add some sort of listener to respond to errors, supply sign-in credentials etc. (this idea obviously needs some fleshing out)
FileSystemDropbox::Listener dropBoxListener;
fileSystem.mount("Cloud Storage/Dropbox", new FileSystemDropbox(dropBoxListener));
// -------------------- Usage -----------------------------
// Read a wav file from the Android APK
InputStream* pWavFileFromAndroidAssets = File("Assets/MySoundFile.wav").createInputStream();
// Obtain a file from a zip archive - the zip file header is loaded lazily on demand, and is unloaded if it hasn't been used for n seconds
InputStream* pFileFromZipArchive = File("Archives/SomeZipFile.zip/SomeFile.dat").createInputStream();
// Get a file from Dropbox - we may need a listener which needs to take some sort of action if sign-in is needed, etc, or at least return a meaningful error code if not signed in so the application can take appropriate action
InputStream* pFileFromDropbox = File("Cloud Storage/Dopbox/SomeFileFromTheCloud.txt").createInputStream();
// Iterate all files in the mounted zip archive
DirectoryIterator* pZipFileIterator = File("Archives/SomeZipFile.zip").createDirectoryIterator(DirectoryIterator::Flag_Recursive, "*.*");
I can think of at least a couple of possible implementations:
- Heavily modify the File and DirectoryIterator code. Advantages : all code can use the virtual file system via the File() class. Disadvantages : Merging in future Juce changes to my local copy.
- Make my own File style class (eg. VirtualFile) which sits outside the core Juce library. Advantages : No modification to Juce. Disadvantages : Only application code can use the virtual file system, but any library code which accepts Input/OutputStreams can still work.
Anyone fancy chipping in with their thoughts?