Skip to content

Latest commit

 

History

History
461 lines (365 loc) · 11.1 KB

README.md

File metadata and controls

461 lines (365 loc) · 11.1 KB

datkt.fs

Asynchronous file system operations for Kotlin built on libuv and based on the file system API for Node.js.

Installation

The datkt.fs package an be installed with NPM.

$ npm install @datkt/fs

Prerequisites

Usage

## Compile a program in 'main.kt' and link fs.klib found in `node_modules/`
$ konanc main.kt $(konanc-config -clr node_modules/@datkt/fs)

where main.kt might be

import datkt.fs.*

fun main(args: Array<String>) {
  mkdir("./directory") { err ->
    if (null != err) {
      println("Failed to make directory: ${err.message}")
    } else {
      writeFile("./directory/file", "hello world") { err ->
        if (null != err) {
          println("Failed to write file: ${err.message}")
        }
      }
    }
  }

  // kick off file system event loop
  datkt.fs.loop.run()
}

API

object loop { ... }

An object that represents an interface into the uv event loop used internally for asynchronous work done by the functions exposed in this package. datkt.fs.loop.run() will invoke any queued work for the event loop.

object loop {
  fun run(): Int
  fun stop()
}

loop.run()

Invoke the uv event loop. Calls uv_run internally.

loop.stop()

Stop the uv event loop. Calls uv_stop internally.

access(path: String, mode: Long = F_OK, callback: (Error?) -> Unit?)

Test user permissions for a file specified at path and mode calling callback with an Error if one errors.

access("/home") { err ->
  if (null != err) {
    println("Something went wrong checking access to /home")
  }
}

The possible values for the mode argument to test file access permissions can be seen below.

  • F_OK - Test for the existence of a file
  • R_OK - Test for read permissions on a file
  • W_OK - Test for write permissions on a file
  • X_OK - Test for execution permissions on a file

Change user permissions of a file specified at path and mode calling callback with an Error if one occurs.

// make read, write, execute permissions for everyone
val mode = (
  S_IRUSR or S_IWUSR or S_IXUSR or
  S_IRGRP or S_IWGRP or S_IXGRP or
  S_IROTH or S_IWOTH or S_IXOTH
)

// modify program permissions
chmod("/home/program", mode) { err ->
  if (null != err) {
    println("Something went wrong changing program permissions: ${err.message}")
  }
}

The possible values for the mode argument can be seen below. They can be grouped into a bit mask by the logical OR (or) operator.

  • S_IRWXU - Read, write, and execute by owner (700)
  • S_IRUSR - Read by owner (400)
  • S_IWUSR - Write by owner (200)
  • S_IXUSR - Execute by owner (100)
  • S_IRWXG - Read, write, and Execute by group (070)
  • S_IRGRP - Read by group (040)
  • S_IWGRP - Write by group (020)
  • S_IXGRP - Execute by group (010)
  • S_IRWXO - Read, write, and execute by others (007)
  • S_IROTH - Read by others (004)
  • S_IWOTH - Write by others (002)
  • S_IXOTH - Execute by others (001)

Change user and group ownership of a file specified at path for user id uid, and group id gid calling callback with an Error, if one occurs.

chown("/home/file", 1000, 10) { err ->
  if (null != err) {
    println("Something went wrong changing file ownership: ${err.message}")
  }
}

Change user and group ownership of a symbolic link specified at path for user id uid, and group id gid calling callback with an Error, if one occurs.

symlink("/home/file", "/home/link") { err ->
  lchown("/home/link", 1000, 10) { err ->
    if (null != err) {
      println("Something went wrong changing link ownership: ${err.message}")
    }
  }
}

Create a new hard link at path for a file specified at source calling callback with an Error, if one occurs.

link("/home/file", "/home/link") { err ->
  if (null != err) {
    println("Something went creating hard link: ${err.message}")
  }
}
symlink("/home/file", "/home/symlink") { err ->
  if (null != err) {
    println("Something went creating soft link: ${err.message}")
  }
}

Query the stats of a file specified at path, if it exists, calling callback with an Error, if one occurs, otherwise an instance of Stats as the second argument.

stat("/home/file") { err, stats ->
  if (null != err) {
    println(err.message)
  } else {
    println(stats)
  }
}

Query the stats of a file specified at path, if it is a link or file, calling callback with an Error, if one occurs, otherwise an instance of Stats as the second argument.

lstat("/home/file") { err, stats ->
  if (null != err) {
    println(err.message)
  } else {
    println(stats)
  }
}

Make a directory specified at path with with mode calling calling with an Error, if one occurs. The mode defaults to DEFAULT_MKDIR_MODE (see below) if not specified.

mkdir("/path/to/directory") { err ->
  if (null != err) {
    println(err.message)
  }
}

See File Modes for a list of all file modes. The default mode is defined by the DEFAULT_MKDIR_MODE constant.

val DEFAULT_MKDIR_MODE = (S_IRWXU or S_IRWXG or S_IRWXO)

readdir(path: String, callback: Callback)

Read a directory specified at path for files entries calling callback with an Error, if one occurs, otherwise an Array<String> with file names.

readdir("/home") { err, entries, ->
  for (entry in entries) {
    println(entry)
  }
}

Open a file specified at path with optional flags and mode calling callback with an Error, if one occurs, otherwise with a valid file descriptor.

open("/path/to/file") { err, fd ->
  if (null != err) {
    println(err.message)
  } else {
    // do something with fd
  }
}

By default, all files will be opened in DEFAULT_OPEN_MODE where:

// equivalent to (0666)
val DEFAULT_OPEN_MODE = (
  S_IRUSR or S_IWUSR or
  S_IRGRP or S_IWGRP or
  S_IROTH or S_IWOTH
)
  • "r" - Open file for reading. An error occurs if the file does not exist.
  • "r+" - Open file for reading and writing. An error occurs if the file does not exist.
  • "w" - Open file for writing. The file is created if it does not exist, otherwise it is truncated.
  • "w+" - Open file for reading and writing. The file is created if it does not exist, otherwise it is truncated.
  • "a" - Open file for appending. Writes start at the end of the file. The file is created if it does not exist, otherwise it is truncated.
Represents a data class containing stat properties of a file.
class Stats(
  val dev: Long = 0,
  val mode: Long = 0,
  val nlink: Long = 0,
  val uid: Long = 0,
  val gid: Long = 0,
  val rdev: Long = 0,
  val ino: Long = 0,
  val size: Long = 0,
  val blksize: Long = 0,
  val blocks: Long = 0,
  val atime: Long = 0,
  val mtime: Long = 0,
  val ctime: Long = 0,
  val birthtime: Long = 0
)

Check if a given mode is present in the stat's mode bit field.

if (stat.hasMode(S_IFREG)) {
  // stat points to a regular file
}

Check if the stat points to a character device. Equivalent to stat.hasMode(S_IFCHR).

if (stat.isCharacterDevice()) {
  // stat points to a character device
}

Stats.isSymbolicLink(): Boolean

Check if the stat points to a symbolic link. Equivalent to stat.hasMode(S_IFLNK).

if (stat.isSymbolicLink()) {
  // stat points to a symbolic link
}

Stats.isBlockDevice(): Boolean

Check if the stat points to a block device. Equivalent to stat.hasMode(S_IFBLK).

if (stat.isBlockDevice()) {
  // stat points to a block device
}

Stats.isDirectory(): Boolean

Check if the stat points to a directory. Equivalent to stat.hasMode(S_IFDIR).

if (stat.isDirectory()) {
  // stat points to a directory
}

Check if the stat points to a socket. Equivalent to stat.hasMode(S_IFSOCK).

if (stat.isSocket()) {
  // stat points to a socket
}

Check if the stat points to a FIFO. Equivalent to stat.hasMode(S_IFIFO).

if (stat.isFIFO()) {
  // stat points to a FIFO (named pipe)
}

Stats.isFile(): Boolean

Check if the stat points to a regular file. Equivalent to stat.hasMode(S_IFREG).

if (stat.isFile()) {
  // stat points to a file
}

MIT