6.54. kink/io/FILE¶
Operates files in the filesystem.
6.54.1. FILE.open_to_read(Path ...[$config={}])¶
`open_to_read` opens the file specified by `Path` as a byte input stream. The result supports `input` type.
Config methods:
• C.no_buffer / C.buffer(Max_buf_size)
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = a fun which raises an exception
When the file is opened, `open_to_read` tail-calls $success with an `input`.
If an IO error occurs, `open_to_read` tail-calls $error with an `exception`.
Buffering
The result `input` performs userspace buffering by default.
To limit the buffer size, call C.buffer. The byte length of the buffer does not exceed `Max_buf_size`.
To disable userspace buffering, call C.no_buffer.
Preconditions
`Path` must be a `str`.
`Max_buf_size` must be a positive int `num`.
$success must be a fun which takes an `input`.
$error must be a fun which takes an `exception`.
Example
:FILE.require_from('kink/io/')
:CONTROL.require_from('kink/')
CONTROL.with_finally{(:finally)
:In = FILE.open_to_read('/dev/urandom')
finally{ In.close }
:Bin = In.read(10)
stdout.print_line(Bin.repr)
}
# Output differs each time:
# (bin 0xbe 0x62 0xe8 0x75 0xd4 0x88 0xd4 0xfc 0xc4 0x31)
:Result <- FILE.open_to_read('/no/such/file'){(:O)
O.on_error{(:Exc) 'error: {}'.format(Exc.message) }
}
stdout.print_line(Result.repr)
# => "error: cannot open to read: \"/no/such/file\""
6.54.2. FILE.open_to_scan(Path Charset ...[$config={}])¶
`open_to_scan` opens the file specified by `Path` as a character input stream. The result supports both `scanner` and `input` types.
Config methods:
• C.no_buffer / C.buffer(Max_buf_size)
• C.replace_conversion_error
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = a fun which raises an exception
If the file is opened, `open_to_scan` tail-calls $success with the scanner+input.
If an IO error occurs, `open_to_scan` tail-calls $error with an `exception`.
Buffering
The result scanner+input performs userspace buffering by default.
To limit the buffer size, call C.buffer. The byte length of the buffer does not exceed `Max_buf_size`.
To disable userspace buffering, call C.no_buffer.
String decoding
`Charset` is used to decode bytes into strings.
When `scan_line` or `scan` methods detect malformed byte sequence or a character which cannot be mapped to Unicode, an IO error occurs by default.
If C.replace_conversion_error is called, `scan` and `scan_line` insert replacement character sequence into the string instead of an IO error.
Preconditions
`Path` must be a `str`.
`Charset` must be a `charset`.
`Max_buf_size` must be a positive int num.
$success must be a fun which takes a scanner+input
$error must be a fun which takes an `exception`
6.54.3. FILE.open_to_write(Path ...[$config={}])¶
`open_to_write` opens the file specified by `Path` as a byte output stream. The result supports `output` type.
Config methods:
• C.append
• C.no_buffer / C.buffer(Max_buf_size)
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = a fun which raises an exception
If the file is successfully opened, `open_to_write` tail-calls $success with an `output`.
If an IO error occurs, `open_to_write` tail-calls $error with an `exception`.
Truncation and creation
If the specified file exists, by default, `open_to_write` truncates the file to length 0.
If the specified file exists, and C.append is called, `open_to_write` opens the file without truncating the content. The file pointer is set at the end of the file.
If the specified file does not exist, `open_to_write` makes a new empty file.
Buffering
The result `output` performs userspace buffering by default.
To limit the buffer size, call C.buffer. The byte length of the buffer does not exceed `Max_buf_size`.
To disable userspace buffering, call C.no_buffer.
Preconditions
`Path` must be a `str`.
`Max_buf_size` must be a positive int `num`.
$success must be a fun which takes an `output`.
$error must be a fun which takes an `exception`.
Example
:FILE.require_from('kink/io/')
:CONTROL.require_from('kink/')
:CHARSET.require_from('kink/')
CONTROL.with_finally{(:finally)
:Out = FILE.open_to_write('/dev/stdout')
finally{ Out.close }
Out.write(CHARSET.ascii.str_to_bin("hello\n"))
}
# => hello
6.54.4. FILE.open_to_print(Path Charset Newline ...[$config={}])¶
`open_to_print` opens the file specified by `Path` as a character output stream. The result supports both `printer` and `output` types.
Config methods:
• C.append
• C.no_buffer / C.buffer(Max_buf_size)
• C.flush_on_print
• C.replace_conversion_error
• C.synchronize
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = a fun which raises an exception
If a file is successfully open, `open_to_print` tail-calls $success with a printer+output.
If an IO error occurs, `open_to_print` tail-calls $error with an `exception`.
`Newline` will be used by `printe_line` method as the line separator.
Truncation and creation
If the specified file exists, by default, `open_to_print` truncates the file to length 0.
If the specified file exists, and C.append is called, `open_to_print` opens the file without truncating the content. The file pointer is set at the end of the file.
If the specified file does not exist, `open_to_print` makes a new empty file.
Buffering
The printer+output performs userspace buffering by default.
To limit the buffer size, call C.buffer. The byte length of the buffer does not exceed `Max_buf_size`.
To disable userspace buffering, call C.no_buffer.
If C.flush_on_print is called, and the printer+output is bufferred, the printer+output flushes the buffer after each invocation of `print` and `print_line`.
String encoding
`Charset` will be used to encode strings to bytes.
When a string cannot be encoded, by default, an IO error occurs.
If C.replace_conversion_error is called, `print` and `print_line` methods write replacement byte sequence instead of an IO error.
Synchronization
If C.synchronize is called, `write`, `flush`, `print`, `print_line`, and `close` methods are serialized by a single mutex.
Preconditions
`Path` must be a `str`.
`Charset` must be a `charset`.
`Newline` must be a `str`.
`Max_buf_size` must be a positive int `num`.
$success must be a fun which takes a printer+output.
$error must be a fun which takes an `exception`.
6.54.5. FILE.mkdir(Path ...[$config={}])¶
`mkdir` makes a directory named `Path`.
Config methods:
• C.on_success($success): default = {}
• C.on_error($error): default = a fun which raises an exception
If a directory is successfully made, `mkdir` tail-calls $success with no arg.
If an IO error occurs, `mkdir` tail-calls $error with an `exception`.
Preconditions
`Path` must be a `str`.
$success must be a fun which takes no arg.
$error must be a fun which takes an `exception`.
6.54.6. FILE.rm(Path ...[$config={}])¶
`rm` removes an filesystem entry named `Path`.
Config methods:
• C.on_success($success): default = {}
• C.on_error($error): default = a fun which raises an exception
If the filesystem entry is successfully removed, `rm` tail-calls $success with no arg.
If an IO error occurs, `rm` tail-calls $error with an `exception`.
Preconditions
`Path` must be a str.
$success must be a fun which takes no arg.
$error must be a fun which takes an `exception`.
6.54.7. FILE.ls(Dir_path ...[$config={}])¶
`ls` fetches the entries directly under the directory specified by `Dir_path`. The paths of the entries will have the parts of `Dir_path` as the leading parts. `ls` returns a `vec` of the paths of the entries.
Config methods:
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = a fun which raises an exception
If entries are fetched successfully, `ls` tail-calls $success with a `vec` of the paths.
If an IO error occurs, `ls` tail-calls $error with an `exception`.
Preconditions
`Dir_path` must be a str.
$success must be a fun which takes a `vec`.
$error must be a fun which takes an `exception`.
Example
:FILE.require_from('kink/io/')
stdout.print_line(FILE.ls('/home').repr) # => ["/home/jake" "/home/elwood"]
stdout.print_line(FILE.ls('bin').repr) # => ["bin/kinkw.exe" "bin/kink.exe" "bin/kink"]
6.54.8. FILE.ln_s(Target_path Link_path ...[$config={}])¶
`ln_s` makes a symbolic link on `Link_path` which is linked to `Target_path`.
The name of the fun stems from the UNIX command “ln -s target link”.
Config methods:
• C.on_success($success): default = {}
• C.on_error($error): default = a fun which raises an exception
If a symbolic link is successfully made, `ln_s` tail-calls $success with no arg.
If an IO error occurs, `ln_s` tail-calls $error with an `exception`.
Preconditions
`Target_path` must be a `str`.
`Link_path` must be a `str`.
$success must be a fun which takes no arg.
$error must be a fun which takes an `exception`.
Example
$ kink script:":FILE.require_from('kink/io/') FILE.ln_s('target' 'link')"
$ readlink link
target
6.54.9. FILE.readlink(Link_path ...[$config={}])¶
`readlink` fetches the target path of the symbolic link named `Link_path`.
Config methods:
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = a fun which raises an exception
If the symlink is successfully read, `readlink` tail-calls $success with a `str` of the target path.
If an IO error occurs, `readlink` tail-calls $error with an `exception`.
Preconditions
`Link_path` must be a `str`.
$success must be a fun which takes a `str`.
$error must be a fun which takes an `exception`.
Example
$ ln -s target link
$ kink script:":FILE.require_from('kink/io/') stdout.print_line(FILE.readlink('link'))"
target
6.54.10. FILE.realpath(Path ...[$config={}])¶
`realpath` fetches the absolute real path of `Path`, resolving symlinks, hardlinks like '..', duplicated path separators, and so on.
Config methods:
• C.on_success($success): default = VAL.identity
• C.on_error($error): default = a fun which raises an exception
If the real path is successfully read, `realpath` tail-calls $success with a `str` of the real path.
If an IO error occurs, `realpath` tail-calls $error with an `exception`.
Preconditions
`Path` must be a `str`.
$success must be a fun which takes a `str` of the real path.
$error must be a fun which takes an `exception`.
Example
:FILE.require_from('kink/io/')
stdout.print_line(FILE.realpath('/usr/local/bin/..')) # => /usr/local
6.54.11. FILE.basename(Path)¶
`basename` returns the name of the filesystem entry at the last part of `Path`.
If `Path` does not contain such an entry, `basename` returns an empty `str`.
Precondition
`Path` must be a `str`.
Examples
On a Unix like system:
:FILE.require_from('kink/io/')
:base <- {(:Path)
:Base = FILE.basename(Path)
stdout.print_line(Base)
}
base('bin/kink') # => kink
base('/home') # => home
base('/') # =>
On Windows:
:FILE.require_from('kink/io/')
:base <- {(:Path)
:Base = FILE.basename(Path)
stdout.print_line(Base)
}
base('bin/kink.exe') # => kink.exe
base('bin\kink.exe') # => kink.exe
base('C:\Users') # => Users
base('C:/Users') # => Users
base('C:foo') # => foo
base('C:\') # =>
base('C:/') # =>
base('C:') # =>
6.54.12. FILE.dirname(Path)¶
`dirname` returns the path excluding the name of the filesystem entry of the last part of `Path`.
If `Path` does not contain such an filesystem entry, `dirname` returns the path which is semantically equivalent to `Path`.
Precondition
`Path` must be a `str`.
Examples
On a Unix like system:
:FILE.require_from('kink/io/')
:dir <- {(:Path)
:Dir = FILE.dirname(Path)
stdout.print_line(Dir)
}
dir('bin/kink') # => bin
dir('/home') # => /
dir('/') # => /
On Windows:
:FILE.require_from('kink/io/')
:dir <- {(:Path)
:Dir = FILE.dirname(Path)
stdout.print_line(Dir)
}
dir('bin/kink.exe') # => bin
dir('bin\kink.exe') # => bin
dir('C:\Users') # => C:\
dir('C:/Users') # => C:\
dir('C:foo') # => C:
dir('C:\') # => C:\
dir('C:/') # => C:\
dir('C:') # => C:
6.54.13. FILE.pwd¶
`pwd` returns the absolute path of the current directory.
6.54.14. FILE.separator¶
`separator` returns the path separator of the host system.
The result is either "/" or "\".
6.54.15. FILE.file?(Path)¶
`file?` returns whether the current process can determine the filesystem entry named `Path` is a regular file.
6.54.16. FILE.dir?(Path)¶
`dir?` returns whether the current process can determine the filesystem entry named `Path` is a directory.
6.54.17. FILE.symlink?(Path)¶
`symlink?` returns whether the current process can determine the filesystem entry named `Path` is a symbolic link.
6.54.18. FILE.present?(Path)¶
`present?` returns whether the current process can determine the filesystem entry named `Path` exists.