Class ZeroFsFileSystem

java.lang.Object
java.nio.file.FileSystem
io.roastedroot.zerofs.ZeroFsFileSystem
All Implemented Interfaces:
Closeable, AutoCloseable

final class ZeroFsFileSystem extends FileSystem
FileSystem implementation for ZeroFs. Most behavior for the file system is implemented by its default file system view.

Overview of file system design

invalid reference
ZeroFsFileSystem
instances are created by
invalid reference
ZeroFsFileSystems
using a user-provided
invalid reference
Configuration
. The configuration is used to create the various classes that implement the file system with the correct settings and to create the file system root directories and working directory. The file system is then used to create the Path objects that all file system operations use.

Once created, the primary entry points to the file system are

invalid reference
ZeroFsFileSystemProvider
, which handles calls to methods in Files, and
invalid reference
ZeroFsSecureDirectoryStream
, which provides methods that are similar to those of the file system provider but which treat relative paths as relative to the stream's directory rather than the file system's working directory.

The implementation of the methods on both of those classes is handled by the

invalid reference
FileSystemView
class, which acts as a view of the file system with a specific working directory. The file system provider uses the file system's default view, while each secure directory stream uses a view specific to that stream.

File system views make use of the file system's singleton

invalid reference
ZeroFsFileStore
which handles file creation, storage and attributes. The file store delegates to several other classes to handle each of these:
  • invalid reference
    FileFactory
    handles creation of new file objects.
  • invalid reference
    HeapDisk
    handles allocation of blocks to RegularFile instances.
  • invalid reference
    FileTree
    stores the root of the file hierarchy and handles file lookup.
  • invalid reference
    AttributeService
    handles file attributes, using a set of
    invalid reference
    AttributeProvider
    implementations to handle each supported file attribute view.

Paths

The implementation of Path for the file system is
invalid reference
ZeroFsPath
. Paths are created by a
invalid reference
PathService
with help from the file system's configured
invalid reference
PathType
.

Paths are made up of

invalid reference
Name
objects, which also serve as the file names in directories. A name has two forms:
  • The display form is used in Path for toString(). It is also used for determining the equality and sort order of Path objects for most file systems.
  • The canonical form is used for equality of two Name objects. This affects the notion of name equality in the file system itself for file lookup. A file system may be configured to use the canonical form of the name for path equality (a Windows-like file system configuration does this, as the real Windows file system implementation uses case-insensitive equality for its path objects.

The canonical form of a name is created by applying a series of normalizations to the original string. These normalization may be either a Unicode normalization (e.g. NFD) or case folding normalization for case-insensitivity. Normalizations may also be applied to the display form of a name, but this is currently only done for a Mac OS X type configuration.

Files

All files in the file system are an instance of
invalid reference
File
. A file object contains both the file's attributes and content.

There are three types of files:

  • Directory - contains a table linking file names to
    invalid reference
    directory entries
    .
  • RegularFile - an in-memory store for raw bytes.
  • invalid reference
    SymbolicLink
    - contains a path.

invalid reference
ZeroFsFileChannel
,
invalid reference
ZeroFsInputStream
and
invalid reference
ZeroFsOutputStream
implement the standard channel/stream APIs for regular files.

invalid reference
ZeroFsSecureDirectoryStream
handles reading the entries of a directory. The secure directory stream additionally contains a FileSystemView with its directory as the working directory, allowing for operations relative to the actual directory file rather than just the path to the file. This allows the operations to continue to work as expected even if the directory is moved.

A directory can be watched for changes using the WatchService implementation,

invalid reference
PollingWatchService
.

Regular files

RegularFile makes use of a singleton
invalid reference
HeapDisk
. A disk is a resizable factory and cache for fixed size blocks of memory. These blocks are allocated to files as needed and returned to the disk when a file is deleted or truncated. When cached free blocks are available, those blocks are allocated to files first. If more blocks are needed, they are created.

Linking

When a file is mapped to a file name in a directory table, it is linked. Each type of file has different rules governing how it is linked.
  • Directory - A directory has two or more links to it. The first is the link from its parent directory to it. This link is the name of the directory. The second is the self link (".") which links the directory to itself. The directory may also have any number of additional parent links ("..") from child directories back to it.
  • Regular file - A regular file has one link from its parent directory by default. However, regular files are also allowed to have any number of additional user-created hard links, from the same directory with different names and/or from other directories with any names.
  • Symbolic link - A symbolic link can only have one link, from its parent directory.

Thread safety

All file system operations should be safe in a multithreaded environment. The file hierarchy itself is protected by a file system level read-write lock. This ensures safety of all modifications to directory tables as well as atomicity of operations like file moves. Regular files are each protected by a read-write lock which is obtained for each read or write operation. File attributes are protected by synchronization on the file object itself.