Decorative site banner
Project icon

com.io7m.fsbind

  • About
  • Releases
  • Manual
  • Sources
  • License
  • Issues
Maven Central Version Maven Snapshot Code Coverage

fsbind


The fsbind package implements a JSR203 filesystem that can bind existing JSR203 filesystems into a single unified namespace. It is similar in design and goals to PhysicsFS.

Features


  • Bind multiple JSR203 filesystems into a single read-only filesystem.
  • Written in pure Java 21.
  • OSGi ready.
  • JPMS ready.
  • ISC license.
  • High-coverage automated test suite.

Usage


The fsbind package provides a read-only JSR203 filesystem accessible via an fsbind URI scheme. To create a filesystem named example, call:

final FBFilesystem filesystem = (FBFilesystem) FileSystems.newFileSystem(URI.create("fsbind:example:/"), null);

The fsbind filesystem exposes a strict, read-only, in-memory UNIX-like virtual filesystem consisting of virtual directories and other JSR203 filesystems mounted into filesystem tree.

For example, to create a directory hierarchy and mount a zip file into it, it's first necessary to create a directory in the filesystem. This directory is virtual in the sense that it is a complete in-memory fabrication and does not actually involve any file I/O:

final var dir = filesystem.getPath("/", "archives", "zip0"); Files.createDirectory(dir);

Then, we can take an existing ZipFS filesystem and mount it into the virtual filesystem:

final var zipfs = FileSystems.newFileSystem( URI.create("/path/to/some/zip_file.zip"), Map.of(), null ); filesystem.mount( new MountRequest(zipfs.getPath("/"), dir );

This will make the contents of /path/to/some/zip_file.zip accessible at /archives/zip0 inside the virtual filesystem. It is also possible to expose only part of the archive by using a non-root path as the first argument to the MountRequest. For example, if zip_file.zip looks like this:

Length Date Time Name --------- ---------- ----- ---- 0 2025-04-10 20:16 x/ 10 2025-04-10 20:16 x/a.txt 10 2025-04-10 20:16 x/c.txt 10 2025-04-10 20:16 x/b.txt 0 2025-04-10 20:16 y/ 10 2025-04-10 20:16 y/a.txt 0 2025-04-10 20:16 z/ --------- ------- 40 7 files

We may choose to only expose the contents of the x directory:

filesystem.mount( new MountRequest(zipfs.getPath("/x"), dir );

We would then be able to access x/a.txt by opening /archives/zip0/a.txt:

Files.readString(dir.resolve("a.txt"));

Capabilities


The fsbind filesystem is a minimal abstraction over existing JSR203 filesystems and, in most cases, simply delegates operations to those filesystems directly. Operations that imply write access will typically result in a FilesystemException being raised.

The semantics of real filesystems are generally not very well documented, and filesystems differ immensely across platforms. Furthermore, JSR203 filesystem implementations have a great deal of freedom in how they're implemented internally, and a fsbind filesystem usually consists of a set of filesystems which may have very different semantics individually placed into a single unified namespace. Additionally, fsbind takes a much stricter view with respect to paths than JSR203 filesystems usually do. You can, if you are particularly unhinged, mount an fsbind filesystem inside an fsbind filesystem (although they are required to be different instances). This is not recommended.

Therefore, assume the following rules of thumb:

  • If you know a directory is a virtual directory that you created, and you haven't mounted anything over the top of it, then you can safely create directories inside it.
  • You can delete an empty directory that you created.
  • You can only rely on BasicFileAttributes being available. Trying to use anything else will almost certainly result in an exception.
  • You cannot create files.
  • You cannot modify files (including setting file attributes and/or renaming).
  • You cannot delete files.
  • You cannot create directories inside mounted filesystems.
  • You cannot delete directories inside mounted filesystems.
  • You can use the WatchService, but it might not be particularly efficient compared to native services.
  • You should use absolute paths as much as possible; treat relative paths as intermediate values and avoid passing them to the filesystem. Most operations require absolute paths and will raise exceptions if presented with relative paths.

Paths


An fsbind filesystem uses UNIX-like paths. Outside of mounted filesystems, paths are case-insensitive. All resources, whatever the underlying filesystem, are accessed with fsbind paths.

The fsbind filesystem has no concept of a "current directory" and therefore the provider requires the use of absolute instead of relative paths in most instances.

A path component is a string not containing / and not equal to ., .., or ....

An absolute path is the string "/" followed by a list of path components.

A relative path is a non-empty list of path components.

As examples, the following paths are all valid:

/ /a /CAS.qterm/CyberAcme Systems/pty0 a/b/c a

As examples, the following paths are not valid:

/. /.. /CAS.qterm/.../pty0 .

Watch Service


The fsbind filesystem provides a simple-minded WatchService implementation that spawns one virtual thread per registered path, and checks the modification times on those paths at a configurable rate in order to deliver watch events.

It's possible to specify the rate that will be used by providing a configuration value in the environment map used to create the filesystem:

FileSystems.newFileSystem( "fsbind:example:/", Map.of( FBFilesystemProvider.environmentWatchServiceDurationKey(), Duration.ofMillis(250L) ) );

The provided Duration value is the amount of time that each virtual thread will pause between file checks. Smaller values will check more often, publish events more promptly, and entail more file I/O.

Note that this is unlikely to be anywhere near as performant as the native WatchService provided by the JVM for real filesystems.

Releases & Development Snapshots


Releases


You can subscribe to the atom feed to be notified of project releases.

The most recently released version of the package is 0.0.1.

0.0.1 Release (2025-04-16Z)

The compiled artifacts for the release (and all previous releases) are available on Maven Central.

Maven Modules


<dependency> <group>com.io7m.fsbind</group> <artifactId>com.io7m.fsbind.core</artifactId> <version>0.0.1</version> </dependency><dependency> <group>com.io7m.fsbind</group> <artifactId>com.io7m.fsbind.tests</artifactId> <version>0.0.1</version> </dependency>

Development Snapshots


At the time of writing, the current unstable development version of the package is 0.0.2-SNAPSHOT.

Development snapshots may be available in the Central Portal Snapshots repository. Snapshots are published to this repository every time the project is built by the project's continuous integration system, but snapshots do expire after around ninety days and so may or may not be available depending on when a build of the package was last triggered.

Manual


This project does not have any user manuals or other documentation beyond what might be present on the page above.

Sources


This project uses Git to manage source code.

Repository: https://www.github.com/io7m-com/fsbind

$ git clone --recursive https://www.github.com/io7m-com/fsbind

Issues


This project uses GitHub Issues to track issues.

License


Copyright © 2025 Mark Raynsford <code@io7m.com> https://www.io7m.com Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Last Updated 2025-08-09T14:55:46Z