Nasal library/io
The FlightGear forum has a subforum related to: Nasal Scripting |
Nasal scripting |
---|
Nasal internals |
---|
Memory Management (GC) |
This page contains documentation for the io
namespace in Nasal. This namespace provides APIs for input/output (IO) operations on files. The io
namespace is sourced from fgdata/Nasal/io.nas and simgear/simgear/nasal/iolib.c.
Functions
basename()
io.basename(path);
Version added: FG 3.0 (commit)
Returns last element of a path as a string.
- path
- Path as a string.
Examples
var path = '/demo/demo.xml';
print(io.basename(path)); # prints "demo.xml"
var path = 'C:\FlightGear\FlightGear 3.2.0\data';
print(io.basename(path)); # prints "data"
close()
io.close(file);
Flushes and closes the specified file. Returns nil
.
- file
- File object as returned by
open()
.
Example
var path = getprop("/sim/fg-root") ~ '/keyboard.xml';
var file = io.open(path);
print(io.readln(file)); # prints the XML header
io.close(file);
dirname()
io.dirname(path);
Version added: FG 3.0 (commit)
Returns the directory of a path as a string.
- path
- Path as a string.
Examples
var path = '/demo/demo.xml';
print(io.dirname(path)); # prints "/demo/"
var path = 'C:\FlightGear\FlightGear 3.2.0\data';
print(io.dirname(path)); # prints "C:/FlightGear/FlightGear 3.2.0/"
flush()
io.flush(file);
Flushes the file's buffer. This means that the contents of the buffer (a kind of temporary storage) are written to the actual file on the hard disk. Note that the buffer is also flushed when close()
is called.
- file
- File object as returned by
open()
.
Example
var path = getprop("/sim/fg-home") ~ '/Export/demo.txt';
var file = io.open(path, "w"); # create and open file
io.write(file, "Hello, World!"); # write (to the buffer)
var file2 = io.open(path); # open the file separatly
var b = bits.buf(13); # create a buffer
io.read(file2, b, 13); # read file
print(b); # prints nothing
io.flush(file); # flush buffer to file
io.read(file2, b, 13); # read file again
print(b); # prints "Hello, World!"
io.close(file); # close
io.close(file2);
include()
io.include(file);
Version added: FG 3.0 (commit)
Loads a given Nasal file into where the function is called from.
- file
- Path to file as a string. If it is just a filename, it will be assumed that the file is in the same folder as calling script. Otherwise, it will be searched for in the standard FlightGear directories (see Resolving Paths).
Example
io.include("Nasal/geo.nas"); # include the geo namespace
var coord = Coord.new(); # create a new Coord object
coord.set_latlon(0, 0, 2000); # set coordinates
print(coord.alt()); # prints "2000"
load_nasal()
io.load_nasal(file[, module]);
Loads and executes a given Nasal script into a namespace.
- file
- Full path to the Nasal file as a string.
- module
- Optional name of module to load the script into as a string. If not given, the namespace will be the name of the file.
Examples
For the examples, first put the below code in to a new file, $FG_HOME/Export/demo.nas:
var sayHello = func(){
print("Hello, World!");
}
var file = getprop("/sim/fg-home") ~ '/Export/demo.nas';
io.load_nasal(file); # load into "demo" namespace
demo.sayHello(); # "Hello, World!" will be printed
var file = getprop("/sim/fg-home") ~ '/Export/demo.nas';
io.load_nasal(file, "myDemo"); # load into "myDemo" namespace
myDemo.sayHello(); # "Hello, World!" will be printed
open()
io.open(path[, mode]);
Opens the file with the specified mode and returns an iofile
ghost object representing the file.
Mode | Meaning |
---|---|
r
|
Opens a file for input (reading) operations. The file must exist. |
w
|
Creates a new file for output (writing) operations. If the file already exists, its contents will be cleared first. |
a
|
Opens a file for appending data. The file is created if it does not exist. |
r+
|
Open for input and output operations. The file must exist. |
w+
|
Creates a new file for input and output operations. If the file already exists, its contents will be cleared first. |
a+
|
Opens a file for input and output operations. Output operations will append data to the end of the file. Input operations are affected by seek() , but output operations will move the position back to the end of the file. The file is created if it does not exist.
|
rb
|
Opens a file for input operations, treating it as a binary file. The file must exist. Default mode. |
wb
|
Creates a new file for output operations, treating it as a binary file. If the file already exists, its contents will be cleared first. |
ab
|
Opens a file for appending data, treating it as a binary file. The file is created if it does not exist. |
r+b or rb+
|
Open for input and output operations, treating it as a binary file. The file must exist. |
w+b or wb+
|
Creates a new file for input and output operations, treating it as a binary file. If the file already exists, its contents will be cleared first. |
a+b or ab+
|
Opens a file for input and output operations, treating it as a binary file. Output operations will append data to the end of the file. Input operations are affected by seek() , but output operations will move the position back to the end of the file. The file is created if it does not exist.
|
- path
- Full path to the file as a string.
- mode
- Optional mode parameter. See the table below. Defaults to "rb".
Examples
Note that the below example must be run first for the others to work.
var path = getprop("/sim/fg-home") ~ '/Export/demo.txt';
var file = io.open(path, "w"); # open in write mode
var text = 'Hello, World!' ~ "\r";
io.write(file, text);
io.close(file);
var path = getprop("/sim/fg-home") ~ '/Export/demo.txt';
var file = io.open(path, "r"); # open in read mode
print(io.readln(file)); # prints "Hello, World!"
io.close(file);
var path = getprop("/sim/fg-home") ~ '/Export/demo.txt';
var file = io.open(path, "a"); # open in append mode
var text = "\n" ~ 'This is line 2';
io.write(file, text);
io.close(file);
read()
io.read(file, buf, len);
Reads a given number of bytes from the given file and places those bytes into the given buffer. The bytes will be read from the position of the position indicator (this can be changed using seek()
). Failures are thrown as runtime errors. Returns the number of bytes successfully read.
- file
- File object as returned by
open()
. - buf
- Buffer to read bytes into. A new buffer can be created using
bits.buf(size)
. Must not be smaller than len. - len
- Number of bytes to read as an integer. The position indicator will be advanced by this number of bytes. Must not be greater than the size of buf.
Example
var path = getprop("/sim/fg-root") ~ '/Nasal/geo.nas';
var file = io.open(path);
var len = 5;
var buf = bits.buf(len);
io.read(file, buf, len);
print(buf); # prints "# geo"
io.read(file, buf, len);
print(buf); # prints " func"
io.close(file);
read_airport_properties()
io.read_airport_properties(icao, fname[, target]);
Version added: FG 2.4 (commit)
Loads an airport-related XML file. Paths will be concatenated in the following form: $FG_SCENERY/Airports/i/c/a/icao.fname.xml. Returns the data as a props.Node
object or nil
on error. Note that the file must be in the PropertyList format, or else the function will fail.
- icao
- ICAO code of the airport as a string.
- fname
- Filename of the airport data file as a string, e.g., "groundnet", "ils", "jetways", "rwyuse", "threshold", or "twr". See above for its use in the concatenation of the path.
- target
- Optional place to put the results in the Property Tree. May be either a
props.Node
object pointing to a place in the Property Tree or a property path.
Examples
var data = io.read_airport_properties("KSFO", "ils"); # the airport might need changing
props.dump(data); # dump data
var node = props.globals.getNode("demo", 1);
io.read_airport_properties("KSFO", "ils", node); # the airport might need changing
props.dump(node); # dump data
var path = "/demo";
io.read_airport_properties("KSFO", "ils", path); # the airport might need changing
props.dump(props.globals.getNode(path)); # dump data
read_properties()
io.read_properties(path[, target]);
Loads an XML file. Returns the data as a props.Node
object on success or nil
on error. Note that the file must be in the PropertyList format, or else the function will fail.
- path
- Path to the XML file as a string.
- target
- Optional place to put the results in the Property Tree. May be either a
props.Node
object pointing to a place in the Property Tree or a property path.
Examples
var path = getprop("/sim/fg-root") ~ '/keyboard.xml';
var data = io.read_properties(path);
props.dump(data); # dump data
var path = getprop("/sim/fg-root") ~ '/keyboard.xml';
var node = props.globals.getNode("demo", 1);
io.read_properties(path, node);
props.dump(node); # dump data
var path = getprop("/sim/fg-root") ~ '/keyboard.xml';
var node = "/demo";
io.read_properties(path, node);
props.dump(props.globals.getNode(node)); # dump data
readfile()
io.readfile(file);
Reads and returns a complete file as a string. Failures are thrown as runtime errors.
- file
- Path to the file as a string.
Example
var file = getprop("/sim/fg-root") ~ '/Nasal/math.nas';
file = io.readfile(file);
print(file);
readln()
io.readln(file);
Reads and returns a single line from the file, advancing the position indicator. Accepts different newline types, including LF, CR, and CR+LF. Does not include the EOL character(s) in the returned string. End of file or an error is signaled by returning nil
.
- file
- File object as returned by
open()
.
Example
var path = getprop("/sim/fg-root") ~ '/Nasal/bits.nas';
var file = io.open(path);
var line = io.readln(file);
print(line); # prints "var bit = [var _ = 1];"
line = io.readln(file);
print(line); # prints "for (var i = 1; i < 32; i += 1)"
readxml()
io.readxml(path[, prefix]);
Reads an XML file from an absolute path and returns it as a props.Node
object. All nodes will be of the string type. Also, all attributes will be converted in subnodes with a prefix appended. Returns nil
on error.
- path
- Absolute path to the XML file.
- prefix
- Optional prefix to give to the attribute nodes. If it is
nil
, then attributes will be ignored. Defaults to "___" (three underscores).
Example
First, put the following code into $FG_HOME/Export/demo.xml:
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<bar attr1="Hello" attr2="World">abc</bar>
<bar>xyz</bar>
</foo>
var path = getprop("/sim/fg-home") ~ '/Export/demo.xml';
var data = io.readxml(path);
props.dump(data); # dump data
seek()
io.seek(file, position, whence);
Moves the pointer position to a specified place.
- file
- File object as returned by
open()
. - position
- Number of bytes offset from whence as an integer. If whence is
SEEK_SET
, this cannot be negative. - whence
- Specifies position to set the offset from. Must be one of
SEEK_SET
(beginning of file),SEEK_END
(end of file), orSEEK_CUR
(current pointer position).
Example
var path = getprop("/sim/fg-root") ~ '/Nasal/geo.nas';
var file = io.open(path, "r"); # open file
var len = 15;
var buf = bits.buf(len);
io.seek(file, 122, io.SEEK_SET); # set to the desired position
io.read(file, buf, len); # read file
print(buf); # prints "geo.Coord class"
io.close(file); # close file
stat()
io.stat(path);
Calls stat and returns a vector containing 12 pieces of data. See the table below for a list of them in order from first in the vector to last. Returns nil
if the file does not exist.
Data | Meaning |
---|---|
dev | Identifier of device containing file |
ino | Inode number |
mode | Protection mode |
nlink | Reference count of hard links |
uid | User identifier of owner |
gid | Group identifier of owner |
rdev | Device identifier (if special file) |
size | Total file size, in bytes |
atime | Time of last access as a Unix timestamp |
mtime | Time of last modification as a Unix timestamp |
ctime | Time of last status change as a Unix timestamp |
type | Type of file. May be one of "unk", "reg", "dir", "chr", "blk", "fifo", "lnk", or "sock". See simgear/simgear/nasal/iolib.c (line 214). |
- path
- Path to the file as a string.
Example
var path = getprop("/sim/fg-root") ~ '/Nasal/geo.nas';
var stat = io.stat(path);
printf("File size: %s bytes", stat[7]); # prints file size
tell()
io.tell(file);
Returns the current pointer position of the file.
- file
- File object as returned by
open()
.
Example
var path = getprop("/sim/fg-root") ~ '/Nasal/geo.nas';
var file = io.open(path);
io.seek(file, 2, io.SEEK_SET);
print(io.tell(file)); # prints "2"
io.close(file);
write()
io.write(file, string);
Writes a string to a given file and returns the number of bytes successfully written.
- file
- File object as returned by
open()
. - string
- String to write to the file.
Tip It is good practice to make sure that all lines, including the last one, end in a newline (\n ). This will especially help if you will be calling readln() on the file later.
|
Example
var path = getprop("/sim/fg-home") ~ '/Export/demo.txt';
var file = io.open(path, "wb"); # open in write mode
var str = 'Hello World!' ~ "\n";
io.write(file, str); # write the data
io.close(file); # close (and flush) the file stream
write_properties()
io.write_properties(path, prop);
Writes nodes from the Property Tree to an XML file in FlightGear's PropertyList format. If the file does not exist, it will be created. If it does, all contents will be overwritten. Returns the filename on success or nil
on error.
- path
- Path of the file to write to as a string. If it does not have a .xml extension, .xml will be added to it.
- prop
- Either a property path or a
props.Node
object. Note that, when the latter is used, results will be more accurate if it refers to a node in the Property Tree, otherwise the node will have to be copied, which may change the node type.
Examples
var path = getprop("/sim/fg-home") ~ '/Export/demo.xml';
var prop = "/position";
print(io.write_properties(path, prop));
var path = getprop("/sim/fg-home") ~ '/Export/demo.xml';
var prop = props.globals.getNode("position");
print(io.write_properties(path, prop));
var path = getprop("/sim/fg-home") ~ '/Export/demo.xml';
var tree = {
"a": 12.34,
"b": "Hello, World!",
"c": {
"d": [1, 2, 3]
}
};
var prop = props.Node.new(tree);
print(io.write_properties(path, prop));
writexml()
io.basename(path, node[, indent[, prefix]]);
Writes a node structure to an XML file.
- path
- Path of the file to write to as a string. If it does not have a .xml extension, .xml will be added to it.
- node
props.Node
object containing the data to write to the file. Attributes should be included as child nodes with a certain prefix. See alsoreadxml()
. It must also have just one root node.- indent
- Optional string specifying what characters should be used to indent lines. Defaults to one horizontal tab character (\t).
- prefix
- Optional string specifying what prefixes attributes will have.
Examples
var path = getprop("/sim/fg-home") ~ '/Export/demo.xml';
var tree = {
"source": {
___type: "book", # will become an attribute
"title": "The Grand Book of Code",
"author-last": "Echter",
"author-first": "William C.",
"year": "2011",
"publisher": "Pen Publishers",
"city": "Manchester"
}
};
var node = props.Node.new(tree);
io.writexml(path, node);
var path = getprop("/sim/fg-home") ~ '/Export/demo.xml';
var tree = {
"source": {
_attr_type: "book",
"title": "The Grand Book of Code",
"author-last": "Echter",
"author-first": "William C.",
"year": "2011",
"publisher": "Pen Publishers",
"city": "Manchester"
}
};
var node = props.Node.new(tree);
io.writexml(path, node, " ", "_attr_"); # indent using two spaces
Variables
SEEK_CUR
io.SEEK_CUR;
Used with seek()
. Means the offset will be counted from the current pointer postion.
SEEK_END
io.SEEK_END;
Used with seek()
. Means the offset will be counted from the end of the file.
SEEK_SET
io.SEEK_SET;
Used with seek()
. Means the offset will be counted from the beginning of the file.