io.eh

Work with file system and input/output routines. More...

use "io.eh"

Constants

const EOF = -1

Types

type BArrayOStream < OStream;
type IStream < Any;
type OStream < Any;

Functions

def abspath(path: String): String;
def BArrayOStream.len(): Int;
def BArrayOStream.new(): BArrayOStream;
def BArrayOStream.reset();
def BArrayOStream.tobarray(): [Byte];
def can_exec(path: String): Bool;
def can_read(path: String): Bool;
def can_write(path: String): Bool;
def exists(path: String): Bool;
def fcopy(source: String, dest: String);
def fcreate(path: String);
def flist(dir: String): [String];
def flistfilter(dir: String, pattern: String): [String];
def flush();
def fmodified(path: String): Long;
def fmove(source: String, dest: String);
def fopen_a(path: String): OStream;
def fopen_r(path: String): IStream;
def fopen_w(path: String): OStream;
def fremove(path: String);
def fsize(path: String): Long;
def get_cwd(): String;
def is_dir(path: String): Bool;
def IStream.available(): Int;
def IStream.close();
def IStream.read(): Int;
def IStream.readarray(buf: [Byte], ofs: Int, len: Int): Int;
def IStream.readfully(): [Byte];
def IStream.reset();
def IStream.skip(num: Long): Long;
def istream_from_ba(buf: [Byte]): IStream;
def matches_glob(file: String, pattern: String): Bool;
def mkdir(path: String);
def OStream.close();
def OStream.flush();
def OStream.print(a: Any);
def OStream.printf(fmt: String, args: [Any]);
def OStream.println(a: Any);
def OStream.write(b: Int);
def OStream.writeall(input: IStream);
def OStream.writearray(buf: [Byte], ofs: Int, len: Int);
def pathdir(path: String): String;
def pathfile(path: String): String;
def print(a: Any);
def printf(fmt: String, args: [Any]);
def println(a: Any);
def read(): Int;
def readarray(buf: [Byte], ofs: Int, len: Int): Int;
def readline(): String;
def readurl(url: String): IStream;
def relpath(path: String): String;
def set_cwd(dir: String);
def set_exec(path: String, on: Bool);
def set_read(path: String, on: Bool);
def set_write(path: String, on: Bool);
def seterr(err: OStream);
def setin(in: IStream);
def setout(out: OStream);
def skip(num: Long): Long;
def space_free(root: String): Long;
def space_total(root: String): Long;
def space_used(root: String): Long;
def stderr(): OStream;
def stdin(): IStream;
def stdout(): OStream;
def write(b: Int);
def writearray(buf: [Byte], ofs: Int, len: Int);

Description

This header defines routines to work with file system and also input/output through the byte streams.

Work with files

File paths in Alchemy OS are specified Unix-style, i.e. directories in the path are separated with slash ('/'). Paths may include elements this directory "." and parent directory "..". If path starts with slash it is an absolute path from the root of the file system hierarchy. Otherwise, path is relative to the current working directory. For example, "file.txt" is a file in current directory and "../icon.png" is a file in directory parent to current. Absolute and relative paths may be converted into each other by functions abspath and relpath. Current working directory may be obtained with get_cwd and changed with set_cwd.

Standard file system operations include:

Alchemy OS distinguishes three file attributes: the permission to read the file, to write to the file, and to execute the file. Note, that not all attributes are supported on all file systems.

Input and output streams

Reading and writing of files is done through the input and output streams.

IStream is an object from which you can read bytes sequentially, it may be file, internet address, etc... To read data from file you need to open input stream:

var input = fopen_r("somefile.txt") // open file for reading
Then you can read data from input variable. This is done by read method, which returns byte value as a number from 0 to 255. If you have reached the end of the file, method returns -1 (you can use convenient constant EOF). The next program reads entire file and prints integer value of each byte it reads.
var b = input.read()
while (b != EOF) {
  println("Byte: "+b)
  b = input.read()
}
Instead of reading single bytes you can read a block of bytes with readarray, and there are more read* functions for binary files (dataio.eh) or text files (textio.eh).

To close file after reading and free associated resources use close.

input.close()
Similarly, OStream is an object in which you can write bytes. There are two ways to open file for writing - with fopen_w you rewrite file clearing its previous contents and with fopen_a you append new data to the end of the file.
var out = fopen_w("test.txt")             // open file for writing
var buf = new [Byte] {'H','e','l','l','o'}// create byte array
out.writearray(buf, 0, buf.len)           // write bytes from array in the file
out.write('!')                            // write single byte in the file
out.flush()                               // save changes to the file
out.close()                               // and finally close it

"Standard" streams

Every running program has three streams that are already opened and ready for I/O operation: All input/output functions have shorter versions to work with these streams. So, to print something on the terminal instead of
stdout().println("something")
you may write just
println("something")

Constant details

const EOF = -1
Returned by input stream read methods when all data has already been read.

Type details

type IStream < Any;
An input stream is a binary input source from which data can be read in bytes.

type OStream < Any;
An output stream is a binary output source to which data can be written in bytes.

type BArrayOStream < OStream;
Output stream that writes to byte buffer.

Function details

def stdin(): IStream;
Returns the default input stream associated with this process. Functions read, readarray and skip read from this stream. You may assign different stream for input using setin.

def stdout(): OStream;
Returns the default output stream associated with this process. Functions write, writearray, print, println and flush write to this stream. You may assign different stream for output using setout.

def stderr(): OStream;
Returns the default error stream associated with this process. You may assign different stream for error messages using seterr.

def setin(in: IStream);
Redefines default input stream for this process.

def setout(out: OStream);
Redefines default output stream for this process.

def seterr(err: OStream);
Redefines default error stream for this process.

def IStream.read(): Int;
Reads byte from the input stream as unsigned value in range 0..255. If stream has reached its end this function returns EOF.

def IStream.readarray(buf: [Byte], ofs: Int, len: Int): Int;
Reads len bytes from the input stream and writes them to the byte array buf starting at index ofs. The function can end up in reading less bytes if the end of the stream is reached or data is otherwise unavailable. Returns total number of actually read bytes. If no bytes can be read because stream has reached its end EOF is returned.

def IStream.readfully(): [Byte];
Reads until the end of the stream and return data in array.

def IStream.skip(num: Long): Long;
Skips over and discards num bytes of data from the input stream. The function may, for a variety of reasons, end up skipping over some smaller number of bytes, possibly 0. Returns total number of actually skipped bytes.

def IStream.available(): Int;
Returns count of buffered bytes which can be read without blocking.

def IStream.reset();
Resets this stream to the initial state. If stream supports reset this method repositions it to the beginning of the input or other appropriate beginning state. If reset is not supported, this method raises ERR_IO error.

def IStream.close();
Closes this stream and frees associated resources.

def read(): Int;
Reads byte from standard input as unsigned value in range 0..255. If stream has reached its end this function returns EOF.

def readarray(buf: [Byte], ofs: Int, len: Int): Int;
Reads len bytes from the standard input and writes them to the byte array buf starting at index ofs. The function can end up in reading less bytes if the end of the stream is reached or data is otherwise unavailable. Returns total number of actually read bytes. If no bytes can be read because stream has reached its end EOF is returned.

def skip(num: Long): Long;
Skips over and discards num bytes of data from the standard input. The function may, for a variety of reasons, end up skipping over some smaller number of bytes, possibly 0. Returns total number of actually skipped bytes.

def readline(): String;
Reads a single line of text from standard input. UTF-8 encoding is used to decode string.

def OStream.write(b: Int);
Writes specified byte to the output stream.

def OStream.writearray(buf: [Byte], ofs: Int, len: Int);
Writes len bytes from given byte array starting from index ofs to the output stream.

def OStream.writeall(input: IStream);
Writes all data from given input to the output.

def OStream.print(a: Any);
Writes text representation of the given value to the output stream. UTF-8 encoding is used.

def OStream.println(a: Any);
Writes text representation of the given value to the output stream and terminates a line. UTF-8 encoding is used.

def OStream.flush();
Forces any buffered data to be written immediately.

def OStream.printf(fmt: String, args: [Any]);
Writes formatted string to the output stream using given format string and arguments. See String.format description on how formatting is used.

def OStream.close();
Closes this stream and frees associated resources.

def write(b: Int);
Writes specified byte to the standard output.

def writearray(buf: [Byte], ofs: Int, len: Int);
Writes len bytes from given byte array starting from index ofs to the standard output.

def print(a: Any);
Writes text representation of the given value to the standard output. UTF-8 encoding is used.

def println(a: Any);
Writes text representation of the given value to the standard output and terminates a line. UTF-8 encoding is used.

def flush();
Forces any buffered data in stdout to be written immediately.

def printf(fmt: String, args: [Any]);
Writes formatted string to the standard output using given format string and arguments. See String.format description on how formatting is used.

def pathfile(path: String): String;
Returns name of the file represented by this path.

def pathdir(path: String): String;
Returns parent directory for given path. For root directory this function returns null.

def abspath(path: String): String;
Converts given path to the absolute path. Pathnames "." and "path/.." are removed from result. If argument path is relative it is calculated from the current working directory.

def relpath(path: String): String;
Converts given path to the path relative to the current working directory. Pathnames "." and "path/.." are removed from result. If argument path is relative it is calculated from the current working directory.

def fcreate(path: String);
Creates new empty file in the filesystem.

def fremove(path: String);
Removes file or directory from the filesystem. Does nothing if file does not exist. This function can refuse to remove directory if it is not empty.

def mkdir(path: String);
Creates new empty directory in the filesystem.

def fcopy(source: String, dest: String);
Copies contents of file source to file dest. If dest does not exist then new file is created.

def fmove(source: String, dest: String);
Moves file to a new location and/or renames it.

def exists(path: String): Bool;
Tests whether the specified file exists.

def is_dir(path: String): Bool;
Returns true the specified file exists and is a directory.

def fopen_r(path: String): IStream;
Opens given file for reading. File must exist and be accessible for reading.

def fopen_w(path: String): OStream;
Opens given file for writing. If file exists then it must be accessible for writing. The previous contents of the file is erased. If file does not exist then new file is created in the filesystem.

def fopen_a(path: String): OStream;
Opens given file for appending. If file exists then it must be accessible for writing. New data is written to the end of the file. If file does not exist then new file is created in the filesystem.

def flist(dir: String): [String];
Returns file names that the specified directory contains. Directory names are ended with '/'. The pathnames ".." and "." are not included in the return value. If the directory is empty then a zero-length array is returned.

def flistfilter(dir: String, pattern: String): [String];
Returns file names in the specified directory that match given pattern. Symbol '?' represents any character, symbol '*' represents any number of characters. For example, to get list of all files with .txt extension from the current directory:
var files = flistfilter("./", "*.txt")
If you need to search for characters '?' and '*', escape them as "\?" and "\*".

def fmodified(path: String): Long;
Returns time of the last modification of the file. To work with the returned value use functions from time.eh.

def fsize(path: String): Long;
Returns the size of the file in bytes. If size cannot be computed this function returns -1L.

def set_read(path: String, on: Bool);
Changes permission to read from the file. Does nothing if read flag is not supported by the filesystem.

def set_write(path: String, on: Bool);
Changes permission to write to the file. Does nothing if write flag is not supported by the filesystem.

def set_exec(path: String, on: Bool);
Changes permission to execute the file. Does nothing if exec flag is not supported by the filesystem.

def can_read(path: String): Bool;
Tests whether this file exists and has read permission.

def can_write(path: String): Bool;
Tests whether this file exists and has write permission.

def can_exec(path: String): Bool;
Tests whether this file exists and can be executed. Note, that native file system does not support exec flag, so this function always returns true.

def get_cwd(): String;
Gets the current working directory of the process.

def set_cwd(dir: String);
Sets the current working directory of the process. Directory must exist.

def space_total(root: String): Long;
Returns amount of total space in the file system at given mount point. Returns -1L if value is unknown.

def space_free(root: String): Long;
Returns amount of free space in the file system at given mount point. Returns -1L if value is unknown.

def space_used(root: String): Long;
Returns amount of used space in the file system at given mount point. Returns -1L if value is unknown.

def readurl(url: String): IStream;
Opens the specified URL for reading. URL must have the form protocol://address. Supported protocols as of release 2.0:

def matches_glob(file: String, pattern: String): Bool;
Tests if specified file name matches given pattern. Symbol '?' represents any character, symbol '*' represents any number of characters. If you need to match characters '?' and '*', escape them as "\?" and "\*".

def istream_from_ba(buf: [Byte]): IStream;
Creates new input stream that uses given byte array as source of data.

def BArrayOStream.new(): BArrayOStream;
Creates new output stream that writes to byte buffer.

def BArrayOStream.len(): Int;
Returns number of bytes written to this output stream so far.

def BArrayOStream.tobarray(): [Byte];
Allocates new byte array and copies current contents of this output stream in it.

def BArrayOStream.reset();
Resets this output stream discarding previous contents and setting length to zero.