hxFileManager
Cross-platform file management library for Haxe. Provides a clean async API backed by a native thread pool — file I/O, JSON helpers, file watching, hashing, batch operations, and HTTP — all with a consistent interface across Windows, Linux, and Mac.
Installation
Install via haxelib, then call FileManager.init() before any async operation.
haxelib install hxFileManager
import hxFileManager.FileManager;
import hxFileManager.HttpManager;
FileManager.init(); // start the thread pool (call once at startup)
FileManager
Async file operations powered by a configurable worker thread pool. All *Async methods are non-blocking and deliver results via callbacks.
The directory containing the running executable. Empty string on unsupported targets.
trace(FileManager.rootDir); // e.g. "D:/myproject/bin"
Whether the process is running with administrator / root privileges. Evaluated once at startup.
if (FileManager.isAdmin) trace("Running as admin");
Start the worker thread pool. Must be called before any async method. Safe to call multiple times — subsequent calls are no-ops.
| Parameter | Type | Description |
|---|---|---|
| numThreads | Int | Number of worker threads to spawn. Default 4. optional |
FileManager.init(); // 4 threads (default)
FileManager.init(8); // 8 threads
Drain the task queue and terminate all worker threads. Call when the application is shutting down.
FileManager.dispose();
Push arbitrary work onto the shared thread pool. Throws in debug builds if init() has not been called.
FileManager.enqueueAsync(() -> trace("on worker thread"));
Returns true if the path exists and is a file.
if (FileManager.fileExists("save.dat")) trace("save found");
Returns true if the path exists and is a directory.
if (FileManager.folderExists("assets")) trace("assets dir exists");
Async version of fileExists.
FileManager.fileExistsAsync("save.dat", exists -> trace(exists));
Async version of folderExists.
FileManager.folderExistsAsync("assets", exists -> trace(exists));
Read a text file asynchronously.
FileManager.readFileAsync("config.txt", content -> trace(content));
Read a file as raw Bytes asynchronously.
FileManager.readFileBytesAsync("image.png", bytes -> trace(bytes.length));
Write a text file asynchronously. Parent directories are created automatically. onSuccess receives elapsed seconds.
FileManager.writeFileAsync("log.txt", "hello", t -> trace("wrote in " + t + "s"));
Write raw bytes to a file asynchronously.
FileManager.writeBytesAsync("data.bin", myBytes);
Append text to a file. Creates the file if it does not exist.
FileManager.appendFileAsync("log.txt", "\nnew line");
Prepend text to a file by reading existing content and rewriting with new content at the front.
FileManager.prependFileAsync("log.txt", "=== START ===\n");
Erase all content from a file without deleting it.
FileManager.truncateFileAsync("cache.txt");
Atomically write a file. Backs up existing content to .bak first and restores on failure. Removes the backup on success.
FileManager.safeWriteAsync("config.json", newJson);
Read a file and split it into an array of lines.
FileManager.readLinesAsync("data.csv", lines -> trace(lines.length + " rows"));
Write an array of strings to a file joined by newlines.
FileManager.writeLinesAsync("list.txt", ["alpha", "beta", "gamma"]);
Read a file and return its contents Base64-encoded.
FileManager.readFileBase64Async("icon.png", b64 -> sendToServer(b64));
Read and parse a JSON file asynchronously.
FileManager.readJsonAsync("config.json", cfg -> trace(cfg.version));
Serialise data to JSON and write to a file. Pass pretty: true for indented output.
FileManager.writeJsonAsync("config.json", {version: 2}, null, null, true);
Read a JSON file, pass the parsed object through a transform function, then write the result back.
FileManager.patchJsonAsync("scores.json", data -> {
data.highScore = 9999;
return data;
});
Returns a map with keys "size" (Int) and "lastModified" (Date).
FileManager.getFileMetadataAsync("save.dat", meta -> trace(meta.get("size")));
Get file size in bytes.
FileManager.getFileSizeAsync("video.mp4", size -> trace(size + " bytes"));
Get total size of all files inside a folder recursively.
FileManager.getFolderSizeAsync("assets", total -> trace(total + " bytes"));
Get the last modification date of a file.
FileManager.getLastModifiedAsync("save.dat", date -> trace(date.toString()));
Returns the lowercase extension without the leading dot, e.g. "txt", "json".
FileManager.getFileExtension("DATA.JSON"); // "json"
Returns the file name including extension.
FileManager.getFileName("assets/sprites/hero.png"); // "hero.png"
Returns the file name without its extension.
FileManager.getFileNameWithoutExt("assets/sprites/hero.png"); // "hero"
Returns the parent directory of a path.
FileManager.getParentDir("assets/sprites/hero.png"); // "assets/sprites"
Copy a single file. Parent directories are created if needed.
FileManager.copyFileAsync("src.txt", "backup/src.txt");
Recursively copy a folder and all its contents.
FileManager.copyFolderAsync("assets", "backup/assets");
Move a file to a new path.
FileManager.moveFileAsync("temp.dat", "saves/slot1.dat");
Move a folder to a new path.
FileManager.moveFolderAsync("old_saves", "saves/archive");
Delete a file or recursively delete a directory tree.
FileManager.deletePathAsync("temp");
Copy a file next to itself with a suffix before the extension. onDone receives the new path.
FileManager.duplicateFileAsync("save.dat", "_backup", newPath -> trace(newPath));
// produces: "save_backup.dat"
Decode a Base64 string and write the resulting bytes to a file.
FileManager.writeFileBase64Async("icon.png", receivedBase64);
Create a directory and any missing parents recursively.
FileManager.createFolderAsync("saves/slot1/items");
List the immediate contents of a folder.
FileManager.listFilesAsync("assets", entries -> trace(entries));
Recursively list all file paths under a folder.
FileManager.listFilesDeepAsync("assets", all -> trace(all.length + " files"));
List only subdirectory names inside a folder.
FileManager.listFoldersAsync("saves", dirs -> trace(dirs));
Count files in a folder. Set recursive: true to include subdirectories.
FileManager.countFilesAsync("assets", n -> trace(n), true);
Remove all empty subdirectories recursively. onDone receives the count of removed directories.
FileManager.cleanEmptyFoldersAsync("output", n -> trace(n + " dirs cleaned"));
Recursively search for files whose name contains pattern. Returns full paths.
FileManager.searchFilesAsync("assets", "hero", results -> trace(results));
Recursively find all files with a given extension. Accepts "png" or ".png".
FileManager.searchByExtensionAsync("assets", "png", pngs -> trace(pngs.length));
Search inside file contents for a substring. Returns paths of matching files.
FileManager.searchByContentAsync("logs", "ERROR", matches -> trace(matches));
Poll a folder for changes using mtime-hash comparison. Returns a watch ID used to cancel via stopWatcher.
var id = FileManager.watchFolder("assets", () -> trace("changed!"));
FileManager.stopWatcher(id);
Poll a single file for modifications using mtime comparison. Returns a watch ID.
var id = FileManager.watchFile("config.json", () -> reloadConfig());
Stop a running file or folder watcher by its ID.
FileManager.stopWatcher(watchId);
Compute the MD5 hash of a file. Returns a 32-character hex string.
FileManager.hashFileMd5Async("installer.exe", hash -> trace(hash));
Compute the SHA-256 hash of a file. Returns a 64-character hex string.
FileManager.hashFileSha256Async("installer.exe", hash -> trace(hash));
Compare two files byte-for-byte. Callback receives true if identical.
FileManager.compareFilesAsync("v1.dat", "v2.dat", eq -> trace(eq ? "same" : "different"));
Write multiple files in a single async operation.
FileManager.batchWriteAsync(["a.txt" => "hello", "b.txt" => "world"]);
Read multiple files in a single async operation. Returns a map of path → content.
FileManager.batchReadAsync(["a.txt", "b.txt"], map -> trace(map.get("a.txt")));
Delete multiple paths in a single async operation.
FileManager.batchDeleteAsync(["tmp1.txt", "tmp2.txt", "tmp3.txt"]);
Copy multiple source/destination file pairs in one operation.
FileManager.batchCopyAsync([{src: "a.txt", dst: "backup/a.txt"}]);
Move multiple source/destination file pairs in one operation.
FileManager.batchMoveAsync([{src: "inbox/a.txt", dst: "archive/a.txt"}]);
Download a URL to a local path with automatic retry. onProgress receives (bytesReceived, total).
FileManager.downloadFileAsync(
"https://example.com/file.zip", "downloads/file.zip",
null, (r, t) -> trace('$r/$t'), () -> trace("done!")
);
Return a unique path by appending an incrementing counter if the file already exists, e.g. file (2).txt.
FileManager.generateUniqueFileNameAsync("report.pdf", path -> saveAs(path));
Create an empty temporary file in the system temp directory and return its path.
FileManager.createTempFileAsync(path -> trace(path), "myapp_", ".tmp");
Create a temporary directory in the system temp directory and return its path.
FileManager.createTempFolderAsync(path -> trace(path));
Request administrator privileges by re-launching the process with elevation. Native cpp targets only.
if (!FileManager.isAdmin) FileManager.requestAdmin(() -> trace("elevated!"));
Returns "Windows", "Mac", "Linux", or "unknown".
trace(FileManager.getPlatformName()); // "Windows"
Returns the OS-appropriate app data directory for appName, creating it if needed. Uses %APPDATA% on Windows, ~/Library/Application Support on Mac, and ~/.local/share on Linux.
var path = FileManager.getAppDataPath("MyGame");
// Windows → C:/Users/User/AppData/Roaming/MyGame
@:noCompletion) and will be removed in a future version. Use the async equivalents instead.| Deprecated | Use instead |
|---|---|
| createFile | writeFileAsync |
| readFile | readFileAsync |
| readJson | readJsonAsync |
| writeJson | writeJsonAsync |
| deletePath | deletePathAsync |
| safeWrite | safeWriteAsync |
| copyFolderRecursive | copyFolderAsync |
| getFileSize | getFileSizeAsync |
| getFolderSize | getFolderSizeAsync |
| listFiles | listFilesAsync |
| copyFile | copyFileAsync |
| moveFolder / renameFolder | moveFolderAsync |
| renameFile | moveFileAsync |
| deleteFile / deleteFolder | deletePathAsync |
| createFolder | createFolderAsync |
| generateUniqueFileName | generateUniqueFileNameAsync |
| getFileMetadata | getFileMetadataAsync |
| stopWatchingFolder | stopWatcher |
HttpManager
HTTP client with redirect following, retry logic, and JSON helpers. Methods are synchronous — wrap in FileManager.enqueueAsync for non-blocking use.
Cached result of the last checkInternet() call. Updated automatically at startup.
if (HttpManager.hasInternet) trace("online");
User-Agent header sent with every request. Default: "hxFileManager".
HttpManager.defaultUserAgent = "MyApp/1.0";
Request timeout in seconds. Default: 10.
HttpManager.defaultTimeout = 30;
Fetch a URL and return the response body as a string. Follows redirects automatically.
var html = HttpManager.requestText("https://example.com");
Fetch a URL and return the raw response bytes. Follows redirects automatically.
var bytes = HttpManager.requestBytes("https://example.com/file.zip");
Fetch a URL and parse the response body as JSON.
HttpManager.getJson("https://api.example.com/user/1", user -> trace(user.name));
Return the HTTP status code for a URL without downloading the body.
var code = HttpManager.getStatusCode("https://example.com"); // 200
Return all response headers for a URL as a map.
var h = HttpManager.getResponseHeaders("https://example.com");
trace(h.get("content-type"));
Returns true if the URL responds with any bytes. Never throws.
if (HttpManager.hasBytes("https://cdn.example.com/asset.png")) downloadIt();
POST a JSON body. Sets Content-Type: application/json automatically.
HttpManager.postJson("https://api.example.com/scores", {player: "Hero", score: 9999});
POST URL-encoded form fields.
HttpManager.postForm("https://example.com/login", ["user" => "hero", "pass" => "1234"]);
Send a PUT request with a JSON body. Uses X-HTTP-Method-Override: PUT.
HttpManager.putJson("https://api.example.com/user/1", {name: "Hero"});
Send a PATCH request with a JSON body. Uses X-HTTP-Method-Override: PATCH.
HttpManager.patchJson("https://api.example.com/user/1", {score: 100});
Send a DELETE request. Uses X-HTTP-Method-Override: DELETE.
HttpManager.delete("https://api.example.com/user/1");
Download a URL directly to a local file path.
HttpManager.downloadTo("https://example.com/img.png", "img.png");
Retry a GET request up to maxAttempts times with delayMs between attempts. Throws after all fail.
var bytes = HttpManager.requestWithRetry("https://example.com/file.zip", 5, 1000);
Check connectivity by hitting https://example.com. Updates and returns hasInternet.
if (!HttpManager.checkInternet()) trace("no connection");
Check internet connectivity asynchronously.
HttpManager.checkInternetAsync(online -> trace(online ? "online" : "offline"));
Thrown by requestText, requestBytes, and related methods on failure.
| Field | Type | Description |
|---|---|---|
| message | String | Error description. |
| url | String | The URL that caused the error. |
| status | Int | HTTP status code, or -1 if unavailable. |
| redirected | Bool | Whether the error occurred during a redirect. |
try {
var text = HttpManager.requestText("https://bad.url");
} catch (e:HttpError) {
trace(e.toString());
// [HttpManager | ERROR] | Status: 404 | URL: ... | Message: ...
}