{"id":27261340,"url":"https://github.com/datkt/fs","last_synced_at":"2026-05-09T04:31:54.205Z","repository":{"id":143746832,"uuid":"157414511","full_name":"datkt/fs","owner":"datkt","description":"Async file system for Kotlin built on libuv","archived":false,"fork":false,"pushed_at":"2019-04-04T02:36:51.000Z","size":148,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-11T05:37:36.596Z","etag":null,"topics":["async","dat","datkt","file","fs","konan","kotlin","libuv","native","node","npm","package","system","uv"],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/datkt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-11-13T16:52:52.000Z","updated_at":"2025-03-14T07:19:28.000Z","dependencies_parsed_at":null,"dependency_job_id":"e91d973c-36de-476d-b9bc-1b728e0bf496","html_url":"https://github.com/datkt/fs","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/datkt/fs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datkt%2Ffs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datkt%2Ffs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datkt%2Ffs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datkt%2Ffs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/datkt","download_url":"https://codeload.github.com/datkt/fs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/datkt%2Ffs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32807176,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","dat","datkt","file","fs","konan","kotlin","libuv","native","node","npm","package","system","uv"],"created_at":"2025-04-11T05:29:36.570Z","updated_at":"2026-05-09T04:31:54.198Z","avatar_url":"https://github.com/datkt.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"datkt.fs\n========\n\nAsynchronous file system operations for Kotlin built on libuv and based\non the [file system API for Node.js](https://nodejs.org/api/fs.html).\n\n## Installation\n\nThe `datkt.fs` package an be installed with NPM.\n\n```sh\n$ npm install @datkt/fs\n```\n\n## Prerequisites\n\n* [Kotlin/Native](https://github.com/JetBrains/kotlin-native) and the\n  `konanc` command line program.\n\n## Usage\n\n```sh\n## Compile a program in 'main.kt' and link fs.klib found in `node_modules/`\n$ konanc main.kt $(konanc-config -clr node_modules/@datkt/fs)\n```\n\nwhere `main.kt` might be\n\n```kotlin\nimport datkt.fs.*\n\nfun main(args: Array\u003cString\u003e) {\n  mkdir(\"./directory\") { err -\u003e\n    if (null != err) {\n      println(\"Failed to make directory: ${err.message}\")\n    } else {\n      writeFile(\"./directory/file\", \"hello world\") { err -\u003e\n        if (null != err) {\n          println(\"Failed to write file: ${err.message}\")\n        }\n      }\n    }\n  }\n\n  // kick off file system event loop\n  datkt.fs.loop.run()\n}\n```\n\n## API\n\n* [object loop](#loop)\n* [fun access(path, mode, callback)](#access)\n  * [Access Modes](#access-modes)\n* [fun chmod(path, mode, callback)](#chmod)\n  * [File Modes](#chmod-modes)\n* [fun chown(path, uid, gid, callback)](#chown)\n* [fun lchown(path, uid, gid, callback)](#lchown)\n* [fun link(source, path, callback)](#link)\n* [fun symlink(source, path, type, callback)](#symlink)\n* [fun stat(path, callback)](#stat)\n* [fun lstat(path, callback)](#lstat)\n* [fun mkdir(path, mode, callback)](#mkdir)\n* [fun readdir(path, callback)](#readdir)\n* [fun open(path, flags, mode, callback)](#open)\n  * [File System Flags](#file-system-flags)\n* [class Stats(...)](#stats)\n  * [Stats.hasMode(mode)](#stats-hasMode)\n  * [Stats.isCharacterDevice()](#stats-isCharacterDevice)\n  * [Stats.isSymbolicLink()](#stats-isSymbolicLink)\n  * [Stats.isBlockDevice()](#stats-isBlockDevice)\n  * [Stats.isDirectory()](#stats-isDirectory)\n  * [Stats.isSocket()](#stats-isSocket)\n  * [Stats.isFIFO()](#stats-isFIFO)\n  * [Stats.isFile()](#stats-isFile)\n\n### `object loop { ... }`\n\u003ca name=\"loop\" /\u003e\n\nAn `object` that represents an interface into the\n[uv](https://github.com/datkt/uv) event loop used internally for\nasynchronous work done by the functions exposed in this package.\n`datkt.fs.loop.run()` will invoke any queued work for the event loop.\n\n```kotlin\nobject loop {\n  fun run(): Int\n  fun stop()\n}\n```\n\n#### `loop.run()`\n\nInvoke the uv event loop. Calls\n[uv_run](http://docs.libuv.org/en/v1.x/loop.html#c.uv_run) internally.\n\n#### `loop.stop()`\n\nStop the uv event loop. Calls\n[uv_stop](http://docs.libuv.org/en/v1.x/loop.html#c.uv_stop) internally.\n\n### `access(path: String, mode: Long = F_OK, callback: (Error?) -\u003e Unit?)`\n\u003ca name=\"access\" /\u003e\n\nTest user permissions for a file specified at `path` and `mode` calling\n`callback` with an `Error` if one errors.\n\n```kotlin\naccess(\"/home\") { err -\u003e\n  if (null != err) {\n    println(\"Something went wrong checking access to /home\")\n  }\n}\n```\n\n#### Access Modes\n\u003ca name=\"access-modes\" /\u003e\n\nThe possible values for the `mode` argument to test file access\npermissions can be seen below.\n\n* `F_OK` - Test for the existence of a file\n* `R_OK` - Test for read permissions on a file\n* `W_OK` - Test for write permissions on a file\n* `X_OK` - Test for execution permissions on a file\n\n### `chmod(path: String, mode: Long, callback: Callback)`\n\u003ca name=\"chmod\" /\u003e\n\nChange user permissions of a file specified at `path` and `mode` calling\n`callback` with an `Error` if one occurs.\n\n```kotlin\n// make read, write, execute permissions for everyone\nval mode = (\n  S_IRUSR or S_IWUSR or S_IXUSR or\n  S_IRGRP or S_IWGRP or S_IXGRP or\n  S_IROTH or S_IWOTH or S_IXOTH\n)\n\n// modify program permissions\nchmod(\"/home/program\", mode) { err -\u003e\n  if (null != err) {\n    println(\"Something went wrong changing program permissions: ${err.message}\")\n  }\n}\n```\n\n#### File Modes\n\u003ca name=\"chmod-modes\" /\u003e\n\nThe possible values for the `mode` argument can be seen below. They can\nbe grouped into a bit mask by the logical OR (`or`) operator.\n\n* `S_IRWXU` - Read, write, and execute by owner (`700`)\n* `S_IRUSR` - Read by owner (`400`)\n* `S_IWUSR` - Write by owner (`200`)\n* `S_IXUSR` - Execute by owner (`100`)\n* `S_IRWXG` - Read, write, and Execute by group (`070`)\n* `S_IRGRP` - Read by group (`040`)\n* `S_IWGRP` - Write by group (`020`)\n* `S_IXGRP` - Execute by group (`010`)\n* `S_IRWXO` - Read, write, and execute by others (`007`)\n* `S_IROTH` - Read by others (`004`)\n* `S_IWOTH` - Write by others (`002`)\n* `S_IXOTH` - Execute by others (`001`)\n\n### `chown(path: String, uid: Long, gid: Long, callback: Callback)`\n\u003ca name=\"chown\" /\u003e\n\nChange user and group ownership of a file specified at `path` for user\nid `uid`, and group id `gid` calling `callback` with an `Error`, if one\noccurs.\n\n```kotlin\nchown(\"/home/file\", 1000, 10) { err -\u003e\n  if (null != err) {\n    println(\"Something went wrong changing file ownership: ${err.message}\")\n  }\n}\n```\n\n### `lchown(path: String, uid: Long, gid: Long, callback: Callback)`\n\u003ca name=\"lchown\" /\u003e\n\nChange user and group ownership of a symbolic link specified at `path` for\nuser id `uid`, and group id `gid` calling `callback` with an `Error`, if one\noccurs.\n\n```kotlin\nsymlink(\"/home/file\", \"/home/link\") { err -\u003e\n  lchown(\"/home/link\", 1000, 10) { err -\u003e\n    if (null != err) {\n      println(\"Something went wrong changing link ownership: ${err.message}\")\n    }\n  }\n}\n```\n\n### `link(source: String, path: String, callback: Callback)`\n\u003ca name=\"link\" /\u003e\n\nCreate a new hard link at `path` for a file specified at `source`\ncalling `callback` with an `Error`, if one occurs.\n\n```kotlin\nlink(\"/home/file\", \"/home/link\") { err -\u003e\n  if (null != err) {\n    println(\"Something went creating hard link: ${err.message}\")\n  }\n}\n```\n\n### `symlink(source: String, path: String, type: Int = 0, callback: Callback)`\n\u003ca name=\"symlink\" /\u003e\n\n```kotlin\nsymlink(\"/home/file\", \"/home/symlink\") { err -\u003e\n  if (null != err) {\n    println(\"Something went creating soft link: ${err.message}\")\n  }\n}\n```\n\n### `stat(path: String, callback: Callback)`\n\u003ca name=\"stat\" /\u003e\n\nQuery the stats of a file specified at `path`, if it exists, calling\n`callback` with an `Error`, if one occurs, otherwise an instance of\n`Stats` as the second argument.\n\n```kotlin\nstat(\"/home/file\") { err, stats -\u003e\n  if (null != err) {\n    println(err.message)\n  } else {\n    println(stats)\n  }\n}\n```\n\n### `lstat(path: String, callback: Callback)`\n\u003ca name=\"lstat\" /\u003e\n\nQuery the stats of a file specified at `path`, if it is a link or file, calling\n`callback` with an `Error`, if one occurs, otherwise an instance of\n`Stats` as the second argument.\n\n```kotlin\nlstat(\"/home/file\") { err, stats -\u003e\n  if (null != err) {\n    println(err.message)\n  } else {\n    println(stats)\n  }\n}\n```\n\n### `mkdir(path: String, mode: Long = DEFAULT_MKDIR_MODE, callback: Callback)`\n\u003ca name=\"mkdir\" /\u003e\n\nMake a directory specified at `path` with with `mode` calling `calling`\nwith an `Error`, if one occurs. The `mode` defaults to\n`DEFAULT_MKDIR_MODE` (see below) if not specified.\n\n```kotlin\nmkdir(\"/path/to/directory\") { err -\u003e\n  if (null != err) {\n    println(err.message)\n  }\n}\n```\n\n#### Modes\n\u003ca name=\"mkdir-modes\" /\u003e\n\nSee [File Modes](#chmod-modes) for a list of all file modes.\nThe default mode is defined by the `DEFAULT_MKDIR_MODE` constant.\n\n```kotlin\nval DEFAULT_MKDIR_MODE = (S_IRWXU or S_IRWXG or S_IRWXO)\n```\n\n### `readdir(path: String, callback: Callback)`\n\u003ca name=\"readdir\" /\u003e\n\nRead a directory specified at `path` for files entries calling\n`callback` with an `Error`, if one occurs, otherwise an `Array\u003cString\u003e`\nwith file names.\n\n```kotlin\nreaddir(\"/home\") { err, entries, -\u003e\n  for (entry in entries) {\n    println(entry)\n  }\n}\n```\n\n### `open(path: String, flags: String = \"r\", mode: Long = DEFAULT_OPEN_MODE, callback: Callback)\n\u003ca name=\"open\" /\u003e\n\nOpen a file specified at `path` with optional flags and mode calling\n`callback` with an `Error`, if one occurs, otherwise with a valid file\ndescriptor.\n\n```kotlin\nopen(\"/path/to/file\") { err, fd -\u003e\n  if (null != err) {\n    println(err.message)\n  } else {\n    // do something with fd\n  }\n}\n```\n\nBy default, all files will be opened in `DEFAULT_OPEN_MODE` where:\n\n```kotlin\n// equivalent to (0666)\nval DEFAULT_OPEN_MODE = (\n  S_IRUSR or S_IWUSR or\n  S_IRGRP or S_IWGRP or\n  S_IROTH or S_IWOTH\n)\n```\n\n### File System Flags\n\u003ca name=\"file-system-flags\" /\u003e\n\n* `\"r\"` - Open file for reading. An error occurs if the file does not exist.\n* `\"r+\"` - Open file for reading and writing. An error occurs if the file does not exist.\n* `\"w\"` - Open file for writing. The file is created if it does not\n  exist, otherwise it is truncated.\n* `\"w+\"` - Open file for reading and writing. The file is created if it does not\n  exist, otherwise it is truncated.\n* `\"a\"` - Open file for appending. Writes start at the end of the file.\n  The file is created if it does not exist, otherwise it is truncated.\n\n### `class Stats(...)`\n\n\u003ca name=\"stats\" /\u003e\nRepresents a data class containing stat properties of a file.\n\n```kotlin\nclass Stats(\n  val dev: Long = 0,\n  val mode: Long = 0,\n  val nlink: Long = 0,\n  val uid: Long = 0,\n  val gid: Long = 0,\n  val rdev: Long = 0,\n  val ino: Long = 0,\n  val size: Long = 0,\n  val blksize: Long = 0,\n  val blocks: Long = 0,\n  val atime: Long = 0,\n  val mtime: Long = 0,\n  val ctime: Long = 0,\n  val birthtime: Long = 0\n)\n```\n\n#### `Stats.hasMode(mode: Long): Boolean`\n\u003ca name=\"stats-hasMode\" /\u003e\n\nCheck if a given mode is present in the stat's mode bit field.\n\n```kotlin\nif (stat.hasMode(S_IFREG)) {\n  // stat points to a regular file\n}\n```\n\n#### `Stats.isCharacterDevice(): Boolean`\n\u003ca name=\"stats-isCharacterDevice\" /\u003e\n\nCheck if the stat points to a [character\ndevice](https://en.wikipedia.org/wiki/Device_file#Character_devices).\nEquivalent to `stat.hasMode(S_IFCHR)`.\n\n```kotlin\nif (stat.isCharacterDevice()) {\n  // stat points to a character device\n}\n```\n\n#### `Stats.isSymbolicLink(): Boolean`\n\u003ca name=\"stats-isSymbolicLink\" /\u003e\n\nCheck if the stat points to a [symbolic link](\nhttps://en.wikipedia.org/wiki/Symbolic_link).\nEquivalent to `stat.hasMode(S_IFLNK)`.\n\n```kotlin\nif (stat.isSymbolicLink()) {\n  // stat points to a symbolic link\n}\n```\n\n#### `Stats.isBlockDevice(): Boolean`\n\u003ca name=\"stats-isBlockDevice\" /\u003e\n\nCheck if the stat points to a [block\ndevice](https://en.wikipedia.org/wiki/Device_file#Block_devices).\nEquivalent to `stat.hasMode(S_IFBLK)`.\n\n```kotlin\nif (stat.isBlockDevice()) {\n  // stat points to a block device\n}\n```\n\n#### `Stats.isDirectory(): Boolean`\n\u003ca name=\"stats-isDirectory\" /\u003e\n\nCheck if the stat points to a directory. Equivalent to `stat.hasMode(S_IFDIR)`.\n\n```kotlin\nif (stat.isDirectory()) {\n  // stat points to a directory\n}\n```\n\n#### `Stats.isSocket(): Boolean`\n\u003ca name=\"stats-isSocket\" /\u003e\n\nCheck if the stat points to a socket. Equivalent to `stat.hasMode(S_IFSOCK)`.\n\n```kotlin\nif (stat.isSocket()) {\n  // stat points to a socket\n}\n```\n\n#### `Stats.isFIFO(): Boolean`\n\u003ca name=\"stats-isFIFO\" /\u003e\n\nCheck if the stat points to a [FIFO](https://en.wikipedia.org/wiki/Named_pipe).\nEquivalent to `stat.hasMode(S_IFIFO)`.\n\n```kotlin\nif (stat.isFIFO()) {\n  // stat points to a FIFO (named pipe)\n}\n```\n\n#### `Stats.isFile(): Boolean`\n\u003ca name=\"stats-isFile\" /\u003e\n\nCheck if the stat points to a regular file.\nEquivalent to `stat.hasMode(S_IFREG)`.\n\n```kotlin\nif (stat.isFile()) {\n  // stat points to a file\n}\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatkt%2Ffs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatkt%2Ffs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatkt%2Ffs/lists"}