Description
The ability to work with files and filesystems is one of the crucial features that a programming language could provide through its standard library. Even if an application is not built around reading and writing data from storage devices, it still may need access to a filesystem to, for example, read configuration files or write logs.
A constant stream of GitHub issues and feedback on kotlinx-io
suggests a demand for fully-featured multiplatform files and filesystems API.
The API exposed through kotlinx.io.files
package was created to provide some partial file support quickly and is neither well-designed nor covers basic user needs. I'm proposing to review it, extend or redesign it if necessary.
For the purposes of this proposal, file and filesystem-related features could be split into two coarse categories: basic and extended.
Basic features include the minimal necessary features required for working with files and filesystems, something one may expect from any FS-related API. Extended features include everything else.
Basic features
Below is the list of features to be considered as basic file and filesystem features.
Paths
- concatenation/joining;
- segmentation (get a parent path, get file name, file extension);
- resolution (convert relative path to absolute);
- relativization (make a path relative to a base path).
FileSystem features
- create/delete files;
- create/delete directories;
- list the content of a directory;
- files/directory renaming/moving (both atomic and non-atomic);
- files copying;
- directory tree traversal;
- file/directory metadata querying and update (atime/mtime/size/etc., touch);
- basic permissions support (query and update);
- symbolic links support (create, resolve);
- query and change the current working dir;
- temporary file/directory creation.
Files
- read (including reading from an arbitrary offset/position);
- write (including writing at an arbitrary offset/position);
- truncate/resize.
FileSystems
- default system filesystem;
- filesystem aimed for testing.
Most of the features listed above are presented in the vast majority of modern filesystems. However, implementation details for some of them (like file metadata or permissions) vary significantly not only between different operating systems but also within filesystems on the same OS. The way these features will be supported should be decided during the design phase.
Extended features
Extended features include mainly OS- or FS-specific features, niche functionality, or something that is hard to implement reliably.
The list is non-exhaustive.
Paths
- an ability to manipulate with a path corresponding to a filesystem not represented in a current system (i.e. ability to explicitly process Windows paths on Unix host; see Dart paths package docs for an example).
FileSystem features
- special files support (pipes, fifo, locks, shmem, etc.);
- watching FS updates;
- extended permissions support;
- hard links support;
- globs support (find all paths matching a glob like */.txt);
- partitions/mount points/volumes support (query name, root dir, size, capacity, etc.).
FileSystems
- archive file systems: Zip, Tar, etc.
Files
- sendfile/splice support;
- memory mapped files support.
Nice to have features
Not fitting to either of two previous categories, but nice to have features:
- allow wrapping
java.nio.file.FileSystem
on JVM to reuse existing third-party filesystem implementations, like S3-FS.
The plan
The overall plan is to review existing files and filesystem API, redesign it if needed, and then concentrate on supporting all the basic features.
The list of basic features is the subject of change, further subdivision and prioritization.
There are no particular plans regarding features considered extended, but the proposed design should be flexible enough to allow their support in the future.