Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

fs - Filesystem Operations

The fs module provides functions for reading, writing, and watching files and directories.

Interface

/// The type of file system events you are interested in.
/// The short names, e.g. `Access mean ANY kind of access event.
/// The longer names e.g. `AccessOpen mean a more specific subset
/// of the short named class event. There are sometimes multiple
/// levels of this. For example `Modify expresses interest in
/// any modification, `ModifyRename expresses interest in any
/// kind of rename operation, and `ModifyRenameTo expresses interest
/// only on rename to.
///
/// `Established is a special event that happens when the watch is
/// successfully established
type Interest = [
    `Established,
    `Any,
    `Access,
    `AccessOpen,
    `AccessClose,
    `AccessRead,
    `AccessOther,
    `Create,
    `CreateFile,
    `CreateFolder,
    `CreateOther,
    `Modify,
    `ModifyData,
    `ModifyDataSize,
    `ModifyDataContent,
    `ModifyDataOther,
    `ModifyMetadata,
    `ModifyMetadataAccessTime,
    `ModifyMetadataWriteTime,
    `ModifyMetadataPermissions,
    `ModifyMetadataOwnership,
    `ModifyMetadataExtended,
    `ModifyMetadataOther,
    `ModifyRename,
    `ModifyRenameTo,
    `ModifyRenameFrom,
    `ModifyRenameBoth,
    `ModifyRenameOther,
    `ModifyOther,
    `Delete,
    `DeleteFile,
    `DeleteFolder,
    `DeleteOther,
    `Other
];

type WatchEvent = {
    paths: Array<string>,
    event: Interest
};

type FileType = [
    `Dir,
    `File,
    `Symlink,
    `SymlinkDir,
    `BlockDev,
    `CharDev,
    `Fifo,
    `Socket,
    null
];

/// Filesystem metadata. Not all kind fields are possible on all platforms.
/// permissions will only be set on unix platforms, windows will only
/// expose the ReadOnly flag.
type Metadata = {
    accessed: [datetime, null],
    created: [datetime, null],
    modified: [datetime, null],
    kind: FileType,
    len: u64,
    permissions: [u32, `ReadOnly(bool)]
};

/// a directory entry
type DirEntry = {
    path: string,
    file_name: string,
    depth: i64,
    kind: FileType
};

/// Set global parameters for all watches.
///
/// poll_interval: How often to poll a batch, set this to 0 to disable polling. default 1 second.
/// poll_batch_size: How many files to poll per batch, must be positive, default 100
val set_global_watch_parameters: fn(
    ?#poll_interval:[duration, null],
    ?#poll_batch_size:[i64, null]
) -> Result<null, `WatchError(string)>;

/// Watch the specified path for events matching #interest. Return the canonical
/// path of the filesystem object involved in the event, or an error if the
/// watch could not be established. watch updates when,
/// - an event occurs that matches interest
/// - an error occurs when trying to establish the watch
///
/// If you wish to know when the watch is established, you must express interest
/// in the `Established event (which is in the default set). If you do so, you will
/// also get a new established event if you change the interest or the path.
///
/// If path is a directory the watch will report events about immediate children.
/// If the watch could not be established establishement will be retried every
/// time path updates
///
/// Filesystem watches are a limited operating system resource, like file
/// descriptors, or handles.
val watch: fn(?#interest: Array<Interest>, string) -> Result<string, `WatchError(string)>;

/// Watch the specified path for events matching #interest. Return the full event
/// describing what happened, or an error if the watch could not be established.
/// watch_full updates when
/// - an event occurs that matches interest
/// - an error occurs when trying to establish the watch
///
/// If you wish to know when the watch is established, you must express interest
/// in the `Established event (which is in the default set). If you do so, you will
/// also get a new established event if you change the interest or the path.
///
/// If path is a directory the watch will report events about immediate children.
/// If the watch could not be established establishement will be retried every
/// time path updates
///
/// Filesystem watches are a limited operating system resource, like file
/// descriptors, or handles.
val watch_full: fn(?#interest: Array<Interest>, string) -> Result<WatchEvent, `WatchError(string)>;

/// Read the specified file into memory as a utf8 string and return it, or an
/// error if,
/// - path is not a file
/// - path is not valid utf8
/// - an OS specific error occurs while trying to read path
///
/// The file will be read again each time path updates, even if path did not change.
/// Reads are queued and executed in the order they are initiated. For example, if we
/// read_all on path0 and path1, the read of path0 will complete before the read of path1
/// begins. Results are always returned in the same order the reads were queued.
val read_all: fn(string) -> Result<string, `IOError(string)>;

/// Read the specified file into memory as a bytes and return it, or an
/// error if,
/// - path is not a file
/// - an OS specific error occurs while trying to read path
///
/// The file will be read again each time path updates, even if path did not change.
/// Reads are queued and executed in the order they are initiated. For example, if we
/// read_all_bin on path0 and path1, the read of path0 will complete before the read of
/// path1 begins. Results are always returned in the same order the reads were queued.
val read_all_bin: fn(string) -> Result<bytes, `IOError(string)>;

/// Write data to path. If path does not exist it will be created. If path exists it
/// will be truncated and it's contents will be replaced with data.
///
/// A write will occur whenever either path or data updates, even if they did not change.
/// Writes are queued and executed in the order they are initiated. For example, if "hello world"
/// is queued to be written to "foo.txt" and then "bar.txt", the write to "foo.txt" will complete
/// before the write to "bar.txt" begins. Results are always returned in the same order the writes
/// were queued.
val write_all: fn(#path: string, string) -> Result<null, `IOError(string)>;

/// Write data to path. If path does not exist it will be created. If path exists it
/// will be truncated and it's contents will be replaced with data.
///
/// A write will occur whenever either path or data updates, even if they did not change.
/// Writes are queued and executed in the order they are initiated. For example, if "hello world"
/// is queued to be written to "foo.txt" and then "bar.txt", the write to "foo.txt" will complete
/// before the write to "bar.txt" begins. Results are always returned in the same order the writes
/// were queued.
val write_all_bin: fn(#path: string, bytes) -> Result<null, `IOError(string)>;

/// Every time trigger updates, create and return a randomly generated
/// temporary directory, and remove any previous temporary directories.
/// return an error if the temporary directory can't be created.
///
/// if `in` is specified, the temporary directory will be created as a child of `in`
///
/// if `name` is specified, the temporary directory will have either a prefix of name
/// or a suffix of name.
val tempdir: fn(
    ?#in:[null, string],
    ?#name:[null, `Prefix(string), `Suffix(string)],
    Any
) -> Result<string, `IOError(string)>;

/// join parts to path using the OS specific path separator
val join_path: fn(string, @args: [string, Array<string>]) -> string;

/// if path is a file then return path
/// otherwise return an IOError. Check again every time path updates.
val is_file: fn(string) -> Result<string, `IOError(string)>;

/// if path is a directory then return path, otherwise return an IOError.
/// check again every time path updates.
val is_dir: fn(string) -> Result<string, `IOError(string)>;

/// Return the metadata for a filesystem object, or an error. Check again every
/// time an argument updates.
val metadata: fn(?#follow_symlinks: bool, string) -> Result<Metadata, `IOError(string)>;

/// readdir reads a directory and returns an array of directory entries.
/// By default it will read only immediate children, however it can be
/// configured to search at greater depth.
///
/// depth appears in several places, The root path is depth 0, immediate children
/// are depth 1, and so on.
///
/// - min_depth: controls the minimum search depth. default 1.
/// - max_depth: controls the maximum search depth. default 1.
/// - contents_first: directory contents will be arranged
///   before the directory itself. default false.
/// - follow_symlinks: if true, follow symlinks when traversing, default false.
/// - follow_root_symlink: if the root path is a symlink follow it. default true.
/// - same_filesystem: don't traverse across filesystem boundaries. default false.
val readdir: fn(
    ?#max_depth: i64,
    ?#min_depth: i64,
    ?#contents_first: bool,
    ?#follow_symlinks: bool,
    ?#follow_root_symlink: bool,
    ?#same_filesystem: bool,
    string
) -> Result<Array<DirEntry>, `IOError(string)>;

/// create a directory. If all is true (default false) create all intermediate
/// directories as well.
val create_dir: fn(?#all: bool, string) -> Result<null, `IOError(string)>;

/// remove a directory. If all is true (default false) then recursively remove
/// the contents as well. If all is false fail if the directory is not empty.
val remove_dir: fn(?#all: bool, string) -> Result<null, `IOError(string)>;

/// remove a file
val remove_file: fn(string) -> Result<null, `IOError(string)>;