FileSentry is a lightweight, cross-platform Java library for monitoring file changes in real time.
It provides a simple API built on Java NIOβs WatchService, with built-in debouncing and event callbacks.
Supports Windows, Linux, and macOS.
β
 Watch any file for changes in real time
β
 Get notified when a file is modified
β
 Easy to integrate into Swing, JavaFX, or command-line apps
β
 Minimal dependencies (pure Java)
β
 Automatically stops when youβre done
β
 Suitable for:
- Text editors (live reload)
 - Log viewers
 - Developer tools
 - Custom synchronization utilities
 
Maven:
<dependency>
  <groupId>io.github.raghul-tech</groupId>
  <artifactId>filesentry</artifactId>
  <version>1.0.0</version>
</dependency>Below is a complete example that:
- 
Watches sample.txt
 - 
Prints a message when the file changes
 - 
Automatically stops when the program ends
 
import io.github.raghultech.filesentry.FileWatcher;
import java.io.File;
import java.lang.ref.WeakReference;
/**
 * Example of using FileSentry to monitor file changes.
 */
public class ExampleFileWatcher {
    private FileWatcher fileWatcher;
    private transient WeakReference<Thread> fileWatcherThread;
    private File currentFile = new File("sample.txt"); 
    public void watchFileForChanges() {
        stopFileWatcher(); // Stop previous watcher if running
        if (currentFile == null || !currentFile.exists()) {
            System.out.println("File not found: " + currentFile.getAbsolutePath());
            return;
        }
        fileWatcher = new FileWatcher(currentFile);
        
        // 1οΈβ£ Simple modify/create/delete awareness
        fileWatcher.setFileModifyListener(changed -> {
            if (changed) {
                System.out.println(" Simple: File changed.");
                // your reload logic 
            }
        });
        // 2οΈβ£ State listener: existence
        fileWatcher.setFileStateListener(exists -> {
            if (exists) {
                System.out.println(" State: File exists (create/modify).");
            } else {
                System.out.println(" State: File deleted.");
            }
        });
        // 3οΈβ£ Detailed change type
        fileWatcher.setFileChangeListener(type -> {
            switch (type) {
                case CREATED -> System.out.println(" Detailed: File CREATED.");
                case MODIFIED -> System.out.println("οΈ Detailed: File MODIFIED.");
                case DELETED -> System.out.println(" Detailed: File DELETED.");
            }
        });
        Thread watcherThread = new Thread(fileWatcher, "FileWatcher-Thread");
        watcherThread.setDaemon(true); // Allow JVM to exit if only daemon threads remain
        fileWatcherThread = new WeakReference<>(watcherThread);
        watcherThread.start();
    }
    public void stopFileWatcher() {
        if (fileWatcher != null) {
            fileWatcher.stopWatching();
        }
        Thread watcherThread = fileWatcherThread != null ? fileWatcherThread.get() : null;
        if (watcherThread != null && watcherThread.isAlive()) {
            watcherThread.interrupt();
            try {
                watcherThread.join(1000); // Wait for thread to exit
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
    public static void main(String[] args) {
        ExampleFileWatcher watcher = new ExampleFileWatcher();
        watcher.watchFileForChanges();
        // Keep the main thread alive for demonstration
        try {
        	 System.out.println(" Watching file for 60 seconds...");
            Thread.sleep(60000); // Run for 60 seconds
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        watcher.stopFileWatcher();
         System.out.println(" Stopped watching.");
    }
}- Just a short note describing exactly what each listener returns, so no confusion (since you had that question earlier):
 
π Note about Listeners
FileModifyListener: alwaystrueon any event (create, modify, delete)FileStateListener:trueif it is modified or created or file currently exists,falseif deletedFileChangeListener: returns aFileChangeTypeenum (CREATED,MODIFIED,DELETED)
- Compile:
 
javac -cp filesentry-1.0.0.jar ExampleFileWatcher.java2.Run:
java -cp .;filesentry-1.0.0.jar ExampleFileWatcher(On Linux or mac, replace ; with :)
- 
Command-line tools: watch logs or configuration files.
 - 
GUI applications: detect when a file changes and prompt the user to reload.
 - 
Development tools: implement live-reload behavior.
 - 
Scripting: monitor scripts or data files.
 
- 
Zero configuration: Just point it to a file.
 - 
Cross-platform: Works on Windows, Linux, macOS.
 - 
Small footprint: No heavy dependencies.
 - 
Easy to stop: Clean shutdown with stopWatching().
 
- 
FileSentry uses Java NIOβs WatchService internally.
 - 
To avoid memory leaks, always stop your watcher when you no longer need it.
 - 
You can integrate it into larger apps (editors, tools) by starting/stopping in your app lifecycle hooks.
 
- View all releases on the Releases Page.
 - For a detailed log of all changes, refer to the CHANGELOG.md file.
 
- 
We welcome contributions of all kinds:
- 
π οΈ Bug fixes
 - 
π Feature suggestions
 - 
π Documentation improvements
 - 
π§ͺ More usage examples
 
 - 
 
Please check the Contributing Guide before starting.
- If you've encountered a bug, please report it by clicking the link below. This will guide you through the bug-reporting process: β‘οΈ Click here to report a bug
 
- This project is licensed under the MIT License.
 
Email: raghultech.app@gmail.com
If you find this project useful, consider buying me a coffee!