ActiveJ FS is a lightweight asynchronous Java library that provides a tiny abstraction on top of common file operations. It provides upload, download, append, list, copy, move, delete, and other methods for operating with local, remote or distributed storage.
Why ActiveJ FS?
- Asynchronous file system
- Lightweight by design
- Intuitive API that consists of well-known file operations
- Supports atomic file uploads
- Support for client-server communication using custom binary protocol as well as HTTP protocol
- Can be launched as a distributed file system cluster
Where ActiveJ FS can be used?
There are several ActiveJ FS implementations:
- Local ActiveJ FS designed for working with file systems located on a single machine. Ideal to implement a local file storage for your application, for example database storage, backup data storage, local logs storage, etc.
- Client/Server implementations for operating with files that are stored remotely. This implementation supports two protocols:
- Custom TCP-based binary protocol with zero overhead. Resembles FTP, but simpler and more efficient.
- HTTP protocol that allows to define a REST API. It also provides third-party clients like browsers access remote ActiveJ FS servers.
- Cluster ActiveJ FS is designed for distributed big data workload. It's optimized for processing large immutable datasets or append-only files. Cluster ActiveJ FS was intentionally made not POSIX-compilant and works only with immutable files. In this way the whole system is simple, lightweight and resilient to server or network failures. Also, this approach allows to avoid the overhead of master-slave architecture and synchronization of mutable files. With ActiveJ FS you can create distributed, scalable P2P file systems with built-in support for rebalancing, failover, and scalability.
- ActiveJ FS Adapters enable filtering, mounting, transforming file names, adding and removing prefixes, subdirectories, etc.
Streaming file access
download() operations utilize CSP module so files are uploaded/downloaded using asynchronous data streams.
String filename = "hello.txt"; Eventloop eventloop = Eventloop.create().withCurrentThread();Executor executor = Executors.newSingleThreadExecutor(); LocalActiveFs fs = LocalActiveFs.create(eventloop, executor, Paths.get("/tmp/file-storage")); fs.start() .then(() -> ChannelSupplier.of(ByteBufStrings.wrapAscii("Hello World")) .streamTo(fs.upload(filename))) .then(() -> fs.download(filename)) .map(supplier -> supplier.map(buf -> buf.asString(StandardCharsets.US_ASCII))) .then(supplier -> supplier.streamTo(ChannelConsumer.ofConsumer(System.out::println))); eventloop.run();