Apache VFS is a great way to access different file systems in the same way. I particularly like the custom RAM filesystem in my unit tests in order to check code that eventually accesses the actual file system.
For example:
StandardFileSystemManager manager = new StandardFileSystemManager(); manager.init(); manager.resolveFile("ram://root/file.txt").createFile(); // prepare test harness ... manager.resolveFile("ram://root/file.txt").getName(); // do something useful
Annoyingly, Apache VFS API provides a way to check if a file/folder is hidden, but, although it is always possible to manually create hidden files on your system, there is no way to mark a file as hidden in the RAM filesystem.
manager.resolveFile("ram://root/file.txt").isHidden(); // returns false manager.resolveFile("ram://root/.file.txt").isHidden(); // also returns false
The solution is to modify the RAM filesystem and customize its checking of the hidden attribute. This means that we need a new RamFileProvider, a new RamFileSystem and finally a new RamFileObject.
In this example, all files and folders whose names start with a dot will be considered hidden:
public class RamFileProvider extends org.apache.commons.vfs2.provider.ram.RamFileProvider { @Override protected FileSystem doCreateFileSystem(FileName name, FileSystemOptions fileSystemOptions) throws FileSystemException { return new RamFileSystem(name, fileSystemOptions); } private static class RamFileSystem extends org.apache.commons.vfs2.provider.ram.RamFileSystem { public RamFileSystem(FileName rootName, FileSystemOptions fileSystemOptions) { super(rootName, fileSystemOptions); } @Override protected FileObject createFile(AbstractFileName name) throws Exception { return new RamFileObject(name, this); } } private static class RamFileObject extends org.apache.commons.vfs2.provider.ram.RamFileObject { public RamFileObject(AbstractFileName name, RamFileSystem ramFileSystemWithHiddenSupport) { super(name, ramFileSystemWithHiddenSupport); } @Override public boolean isHidden() throws FileSystemException { // this is the important part if (getName().getBaseName().startsWith(".")) { return true; } return super.isHidden(); // in practice, this always return false } } }
Finally, this new RamFileProvider must be registered with your existing FileSystemManager. In my case, I get something like that:
StandardFileSystemManager manager = new StandardFileSystemManager(); manager.init(); manager.addProvider("ram-ext", new RamFileProvider()); manager.resolveFile("ram-ext:///root/file.txt").createFile(); manager.resolveFile("ram-ext:///root/.file.txt").createFile(); ... manager.resolveFile("ram-ext://root/file.txt").isHidden(); // returns false manager.resolveFile("ram-ext://root/.file.txt").isHidden(); // returns true
Note that I did not replace the “ram” filesystem entirely. Although that would have been my preferred option, that would have taken too much time in my little experiment.