OpenEuphoria: Euphoria v4.1

# OpenEuphoria Manual

## Euphoria v4.1

routine or constant name search

| Up |  |  | TOC | Index
<< 7 Included Tools | < 8.5 File System | Up: 8 API Reference | 8.7 Operating System Helpers > | 9 Release Notes >>

## 8.6 I/O

### 8.6.1 Constants

#### 8.6.1.1 STDIN

    include std/io.e
    namespace io
    public constant STDIN

Standard Input

#### 8.6.1.2 STDOUT

    include std/io.e
    namespace io
    public constant STDOUT

Standard Output

#### 8.6.1.3 STDERR

    include std/io.e
    namespace io
    public constant STDERR

Standard Error

#### 8.6.1.4 SCREEN

    include std/io.e
    namespace io
    public constant SCREEN

Screen (Standard Out)

#### 8.6.1.5 EOF

    include std/io.e
    namespace io
    public constant EOF

End of file

### 8.6.2 Read and Write Routines

#### 8.6.2.1 ##?##

    <built-in> procedure ##?##

displays an object using numbers and braces.

##### Note:

There are no parenthesis delimiting the single argument to this procedure. This is a unique shortcut in Euphoria syntax.

##### Comments:

This is a shorthand way of writing `pretty_print(STDOUT, x, {})`. An object or an expression is printed to the standard output with braces and indentation to show the structure.

##### Example 1:

    ? {1, 2} + {3, 4}  -- will display {4, 6}

##### See Also:

print

#### 8.6.2.2 print

    <built-in> procedure print(integer fn, object x)

displays an object using numbers and braces.

##### Comments:

All data objects are in binary format within computer hardware; something that is easy to forget. An output routine must convert these binary values into "text" to be human readable. The procedures `print` and `?` produce a "text" representation of an object that is output to a file or device. The text shows the numerical form of the object. If the object `x` is a sequence it uses braces `{ , , , }` to show the structure.

##### Parameters:

1. `fn` : an integer, the handle to a file or device to output to
2. `x` : the object to print

##### Errors:

The target file or device must be open and able to be written to.

##### Comments:

This is not used to write to "binary" files as it only outputs text.

##### Example 1:

    include std/io.e
    print(STDOUT, "ABC")   -- output is:  "{65,66,67}"
    puts (STDOUT, "ABC")    -- output is:  "ABC"
    print(STDOUT, "65")    -- output is:  "65"
    puts (STDOUT, 65)       -- output is:  "A"  (ASCII-65 ==> 'A')
    print(STDOUT, 65.1234) -- output is:  "65.1234"
    puts (STDOUT, 65.1234)  -- output is:  "A" (Converts to integer first)

##### Example 2:

    include std/io.e
    print(STDOUT, repeat({10,20}, 3)) -- output is: {{10,20},{10,20},{10,20}}

##### See Also:

?, puts

#### 8.6.2.3 printf

    <built-in> procedure printf(integer fn, sequence format, object values)

prints one or more values to a file or device, using a format string to embed them in and define how they should be represented.

##### Parameters:

1. `fn` : an integer, the handle to a file or device to output to
2. `format` : a sequence, the text to print. This text may contain format specifiers.
3. `values` : usually, a sequence of values. It should have as many elements as format specifiers in `format`, as these values will be substituted to the specifiers.

##### Errors:

If there are less values to show than format specifiers, a run time error will occur.

The target file or device must be open.

##### Comments:

A format specifier is a string of characters starting with a percent sign ( % ) and ending in a letter. Some extra information may come in between those.

This procedure writes out the `format` text to the output file `fn`, replacing format specifiers with the corresponding data from the `values` parameter. Whenever a format specifiers is found in `format`, the n-th item in `values` will be turned into a string according to the format specifier. The resulting string will the format specifier. This means that the first format specifier uses the first item in `values`, the second format specifier the second item, and so on.

You must have at least as many items in `values` as there are format specifiers in `format`. This means that if there is only one format specifier then `values` can be either an atom, integer or a non-empty sequence. And when there are more than one format specifier in `format` then `values` must be a sequence with a length that is greater than or equal to the number of format specifiers present.

This way, `printf` always takes exactly three arguments no matter how many values are to be printed.

The basic format specifiers are:

- `%d` -- print an atom as a decimal integer
- `%x` -- print an atom as a hexadecimal integer. Negative numbers are printed in two's complement, so -1 will print as `FFFFFFFF`
- `%o` -- print an atom as an octal integer
- `%s` -- print a sequence as a string of characters, or print an atom as a single character
- `%e` -- print an atom as a floating-point number with exponential notation
- `%f` -- print an atom as a floating-point number with a decimal point but no exponent
- `%g` -- print an atom as a floating-point number using whichever format seems appropriate, given the magnitude of the number
- `%%` -- print the `'%'` character itself. This is not an actual format specifier.

Field widths can be added to the basic formats (for example: `%5d, %8.2f, %10.4s`). The number before the decimal point is the minimum field width to be used. The number after the decimal point is the precision to be used for numeric values.

If the field width is negative (for example `%-5d`) then the value will be left-justified within the field. Normally it will be right-justified, even strings. If the field width starts with a leading 0 (for example `%08d`) then leading zeros will be supplied to fill up the field. If the field width starts with a `'+'` (for example `%+7d` ) then a plus sign will be printed for positive values.

##### Comments:

Watch out for the following common mistake. The intention is to output all the characters in the third argument but actually only outputs the first character:

    include std/io.e
    sequence name="John Smith"
    printf(STDOUT, "My name is %s", name)
       --> My name is J

The output of this will be `My name is J` because each format specifier uses exactly one item from the `values` parameter. In this case we have only one specifier so it uses the first item in the `values` parameter, which is the character `'J'`. To fix this situation, you must ensure that the first item in the `values` parameter is the entire text string and not just a character, so you need code this instead:

    include std/io.e
    name="John Smith"
    printf(STDOUT, "My name is %s", {name})
       --> My name is John Smith

Now, the third argument of `printf` is a one-element sequence containing all the text to be formatted.

Also note that if there is only one format specifier then `values` can simply be an atom or integer.

##### Example 1:

    include std/io.e
    atom rate = 7.875
    printf(STDOUT, "The interest rate is: %8.2f\n", rate)

    --      The interest rate is:     7.88

##### Example 2:

    include std/io.e
    sequence name="John Smith"
    integer score=97
    printf(STDOUT, "%15s, %5d\n", {name, score})

    -- "     John Smith,    97"

##### Example 3:

    include std/io.e
    printf(STDOUT, "%-10.4s $ %s", {"ABCDEFGHIJKLMNOP", "XXX"})
    --      ABCD       $ XXX

##### Example 4:

    include std/io.e
    printf(STDOUT, "%d  %e  %f  %g", repeat(7.75, 4))
                      -- same value in different formats

    --      7  7.750000e+000  7.750000  7.75

NOTE that `printf` cannot use an item in `values` that contains nested sequences. Thus this is an error ...

    include std/io.e
    sequence name = {"John", "Smith"}
    printf(STDOUT, "%s", {name} )

because the item that is used from the `values` parameter contains two subsequences (strings in this case). To get the correct output you would need to do this instead ...

    include std/io.e
    sequence name = {"John", "Smith"}
    printf(STDOUT, "%s %s", {name[1], name[2]} )

##### See Also:

sprintf, sprint, print

#### 8.6.2.4 puts

    <built-in> procedure puts(integer fn, object text)

outputs text characters to a screen or file.

##### Parameters:

1. `fn` : an integer, the handle to an opened file or device
2. `text` : an object, either a single character or a sequence of characters.

##### Errors:

The target file or device must be open.

##### Comments:

This procedures outputs, to a file or device, a single byte (atom) or sequence of bytes. The low order 8-bits of each value is actually sent out. If outputting to the screen you will see text characters displayed.

When you output a sequence of bytes it must not have any sub-sequences within it. It must be a sequence of atoms only. (Typically a string of ASCII codes).

Avoid outputting 0's to the screen or to standard output. Your output might get truncated.

Remember that if the output file was opened in text mode, Windows will change `\n` (10) to `\r\n` `(13 10)`. Open the file in binary mode if this is not what you want.

##### Example 1:

    include std/io.e
    puts(SCREEN, "Enter your first name: ")

##### Example 2:

    puts(output, 'A')  -- the single byte 65 will be sent to output

##### See Also:

print

#### 8.6.2.5 getc

    <built-in> function getc(integer fn)

gets the next character (byte) from a file or device `fn`.

##### Parameters:

1. `fn` : an integer, the handle of the file or device to read from.

##### Returns:

An integer, the character read from the file, in the 0..255 range. If no character is left to read, EOF is returned instead.

##### Errors:

The target file or device must be open.

##### Comments:

File input using `getc` is buffered, that means `getc` does not actually go out to the disk for each character. Instead, a large block of characters will be read in at one time and returned to you one by one from a memory buffer.

When `getc` reads from the keyboard, it will not see any characters until the user presses Enter. Note that the user can type Control+Z, which the operating system treats as "end of file" returning EOF.

##### See Also:

gets, get_key

#### 8.6.2.6 gets

    <built-in> function gets(integer fn)

gets a sequence of characters.

##### Parameters:

1. `fn` : an integer, the handle of the file or device to read from.

##### Returns:

An object, either EOF on end of file, or the next line of text from the file.

##### Errors:

The file or device must be open.

##### Comments:

This function gets the next sequence (one line, including `'\n'`) of characters from a file or device. The characters will have values from 0 to 255.

If the line had an end of line marker, a `~'\n'~` terminates the line. The last line of a file needs not have an end of line marker.

After reading a line of text from the keyboard, you should normally output a `\n` character, (for example `puts(1, '\n')` ), before printing something. Only on the last line of the screen does the operating system automatically scroll the screen and advance to the next line.

When your program reads from the keyboard, the user can type Control+Z, which the operating system treats as "end of file". EOF will be returned.

##### Example 1:

    sequence buffer
    object line
    integer fn

    -- read a text file into a sequence
    fn = open("my_file.txt", "r")
    if fn = -1 then
        puts(1, "Couldn't open my_file.txt\n")
        abort(1)
    end if

    buffer = {}
    while 1 do
        line = gets(fn)
        if atom(line) then
            exit   -- EOF is returned at end of file
        end if
        buffer = append(buffer, line)
    end while

##### Example 2:

    object line

    puts(1, "What is your name?\n")
    line = gets(0)  -- read standard input (keyboard)
    line = line[1..$-1] -- get rid of \n character at end
    puts(1, '\n')   -- necessary
    puts(1, line & " is a nice name.\n")

##### See Also:

getc, read_lines

#### 8.6.2.7 get_bytes

    include std/io.e
    namespace io
    public function get_bytes(integer fn, integer n)

reads the next bytes from a file.

##### Parameters:

1. `fn` : an integer, the handle to an open file to read from.
2. `n` : a positive integer, the number of bytes to read.

##### Returns:

A sequence, of length at most `n`, made of the bytes that could be read from the file.

##### Comments:

When `n` `> 0` and the function returns a sequence of length less than `n` you know you have reached the end of file. Eventually, an empty sequence will be returned.

This function is normally used with files opened in binary mode, `"rb"`. This avoids the confusing situation in text mode where Windows will convert CR LF pairs to LF.

##### Example 1:

    integer fn
    fn = open("temp", "rb")  -- an existing file

    sequence whole_file
    whole_file = {}

    sequence chunk

    while 1 do
        chunk = get_bytes(fn, 100) -- read 100 bytes at a time
        whole_file &= chunk        -- chunk might be empty, that's ok
        if length(chunk) < 100 then
            exit
        end if
    end while

    close(fn)
    ? length(whole_file)  -- should match DIR size of "temp"

##### See Also:

getc, gets, get_integer32, get_dstring

#### 8.6.2.8 get_integer32

    include std/io.e
    namespace io
    public function get_integer32(integer fh)

reads the next four bytes from a file and returns them as a single integer.

##### Parameters:

1. `fh` : an integer, the handle to an open file to read from.

##### Returns:

An atom, between `-1` and `power(2,32)-1`, made of the bytes that could be read from the file. When an end of file is encountered, it returns `-1`.

##### Comments:

- This function is normally used with files opened in binary mode, `"rb"`.

##### Example 1:

    integer fn
    fn = open("temp", "rb")  -- an existing file

    atom file_type_code
    file_type_code = get_integer32(fn)

##### See Also:

getc, gets, get_bytes, get_dstring

#### 8.6.2.9 get_integer16

    include std/io.e
    namespace io
    public function get_integer16(integer fh)

reads the next two bytes from a file and returns them as a single integer.

##### Parameters:

1. `fh` : an integer, the handle to an open file to read from.

##### Returns:

An integer, made of the bytes that could be read from the file. When an end of file is encountered, it returns `-1`.

##### Comments:

- This function is normally used with files opened in binary mode, `"rb"`.

##### Example 1:

    integer fn
    fn = open("temp", "rb")  -- an existing file

    atom file_type_code
    file_type_code = get_integer16(fn)

##### See Also:

getc, gets, get_bytes, get_dstring

#### 8.6.2.10 put_integer32

    include std/io.e
    namespace io
    public procedure put_integer32(integer fh, atom val)

writes the supplied integer as four bytes to a file.

##### Parameters:

1. `fh` : an integer, the handle to an open file to write to.
2. `val` : an integer

##### Comments:

- This function is normally used with files opened in binary mode, `"wb"`.

##### Example 1:

    integer fn
    fn = open("temp", "wb")

    put_integer32(fn, 1234)

##### See Also:

getc, gets, get_bytes, get_dstring

#### 8.6.2.11 put_integer16

    include std/io.e
    namespace io
    public procedure put_integer16(integer fh, atom val)

writes the supplied integer as two bytes to a file.

##### Parameters:

1. `fh` : an integer, the handle to an open file to write to.
2. `val` : an integer

##### Comments:

- This function is normally used with files opened in binary mode, `"wb"`.

##### Example 1:

    integer fn
    fn = open("temp", "wb")

    put_integer16(fn, 1234)

##### See Also:

getc, gets, get_bytes, get_dstring

#### 8.6.2.12 get_dstring

    include std/io.e
    namespace io
    public function get_dstring(integer fh, integer delim = 0)

read a delimited byte string from an opened file.

##### Parameters:

1. `fh` : an integer, the handle to an open file to read from.
2. `delim` : an integer, the delimiter that marks the end of a byte string. If omitted, a zero is assumed.

##### Returns:

An sequence, made of the bytes that could be read from the file.

##### Comments:

- If the end-of-file is found before the delimiter, the delimiter is appended to the returned string.

##### Example 1:

    integer fn
    fn = open("temp", "rb")  -- an existing file

    sequence text
    text = get_dstring(fn)	-- Get a zero-delimited string
    text = get_dstring(fn, '$')	-- Get a '$'-delimited string

##### See Also:

getc, gets, get_bytes, get_integer32

### 8.6.3 Low Level File and Device Handling

#### 8.6.3.1 LOCK_SHARED

    include std/io.e
    namespace io
    public enum LOCK_SHARED

#### 8.6.3.2 LOCK_EXCLUSIVE

    include std/io.e
    namespace io
    public enum LOCK_EXCLUSIVE

#### 8.6.3.3 file_number

    include std/io.e
    namespace io
    public type file_number(object f)

File number type

#### 8.6.3.4 file_position

    include std/io.e
    namespace io
    public type file_position(object p)

File position type

#### 8.6.3.5 lock_type

    include std/io.e
    namespace io
    public type lock_type(object t)

Lock Type

#### 8.6.3.6 byte_range

    include std/io.e
    namespace io
    public type byte_range(object r)

Byte Range Type

#### 8.6.3.7 open

    <built-in> function open(sequence path, sequence mode, integer cleanup = 0)

opens a file or device, to get the file number.

##### Parameters:

1. `path` : a string, the path to the file or device to open.
2. `mode` : a string, the mode being used o open the file.
3. `cleanup` : an integer, if 0, then the file must be manually closed by the coder. If 1, then the file will be closed when either the file handle's references goes to 0, or if called as a parameter to `delete`.

##### Returns:

A small integer, -1 on failure, else 0 or more.

##### Errors:

There is a limit on the number of files that can be simultaneously opened, currently 40. After this limit is reached the next call to `open` will produce an error.

The length of `path` should not exceed 1_024 characters.

##### Comments:

Possible modes are:

- `"r"` -- open text file for reading
- `"rb"` -- open binary file for reading
- `"w"` -- create text file for writing
- `"wb"` -- create binary file for writing
- `"u"` -- open text file for update (reading and writing)
- `"ub"` -- open binary file for update
- `"a"` -- open text file for appending
- `"ab"` -- open binary file for appending

Files opened for read or update must already exist. Files opened for write or append will be created if necessary. A file opened for write will be set to 0 bytes. Output to a file opened for append will start at the end of file.

On Windows, output to text files will have carriage-return characters automatically added before linefeed characters. On input, these carriage-return characters are removed. A Control+Z character (ASCII 26) will signal an immediate end of file.

I/O to binary files is not modified in any way. Any byte values from 0 to 255 can be read or written. On Unix, all files are binary files, so `"r"` mode and `"rb"` mode are equivalent, as are `"w"` and `"wb"`, `"u"` and `"ub"`, and `"a"` and `"ab"`.

Some typical devices that you can open on Windows are:

- `"CON"` -- the console (screen)
- `"AUX"` -- the serial auxiliary port
- `"COM1"` -- serial port 1
- `"COM2"` -- serial port 2
- `"PRN"` -- the printer on the parallel port
- `"NUL"` -- a non-existent device that accepts and discards output

Close a file or device when done with it, flushing out any still-buffered characters prior.

Windows and Unix: Long filenames are fully supported for reading and writing and creating.

Windows: Be careful not to use the special device names in a file name, even if you add an extension. For example: `CON.TXT`, `CON.DAT`, `CON.JPG` all refer to the `CON` device and not to a file.

##### Example 1:

    integer file_num, file_num95
    sequence first_line
    constant ERROR = 2

    file_num = open("my_file", "r")
    if file_num = -1 then
        puts(ERROR, "couldn't open my_file\n")
    else
        first_line = gets(file_num)
    end if

    file_num = open("PRN", "w") -- open printer for output

    -- on Windows 95:
    file_num95 = open("big_directory_name\\very_long_file_name.abcdefg",
                      "r")
    if file_num95 != -1 then
        puts(STDOUT, "it worked!\n")
    end if

#### 8.6.3.8 close

    <built-in> procedure close(atom fn)

closes a file or device and flushes out any still-buffered characters.

##### Parameters:

1. `fn` : an integer, the handle to the file or device to query.

##### Errors:

The target file or device must be open.

##### Comments:

Any still-open files will be closed automatically when your program terminates.

#### 8.6.3.9 seek

    include std/io.e
    namespace io
    public function seek(file_number fn, file_position pos)

Seek (move) to any byte position in a file.

##### Parameters:

1. `fn` : an integer, the handle to the file or device to `seek`
2. `pos` : an atom, either an absolute 0-based position or -1 to seek to end of file.

##### Returns:

An integer, 0 on success, 1 on failure.

##### Errors:

The target file or device must be open.

##### Comments:

For each open file, there is a current byte position that is updated as a result of I/O operations on the file. The initial file position is 0 for files opened for read, write or update. The initial position is the end of file for files opened for append. It is possible to seek past the end of a file. If you seek past the end of the file, and write some data, undefined bytes will be inserted into the gap between the original end of file and your new data.

After seeking and reading (writing) a series of bytes, you may need to call `seek` explicitly before you switch to writing (reading) bytes, even though the file position should already be what you want.

This function is normally used with files opened in binary mode. In text mode, Windows converts CR LF to LF on input, and LF to CR LF on output, which can cause great confusion when you are trying to count bytes because `seek` counts the Windows end of line sequences as two bytes, even if the file has been opened in text mode.

##### Example 1:

    include std/io.e

    integer fn
    fn = open("my.data", "rb")
    -- read and display first line of file 3 times:
    for i = 1 to 3 do
        puts(STDOUT, gets(fn))
        if seek(fn, 0) then
            puts(STDOUT, "rewind failed!\n")
        end if
    end for

##### See Also:

get_bytes, puts, where

#### 8.6.3.10 where

    include std/io.e
    namespace io
    public function where(file_number fn)

retrieves the current file position for an opened file or device.

##### Parameters:

1. `fn` : an integer, the handle to the file or device to query.

##### Returns:

An atom, the current byte position in the file.

##### Errors:

The target file or device must be open.

##### Comments:

The file position is is the place in the file where the next byte will be read from, or written to. It is updated by reads, writes and seeks on the file. This procedure always counts Windows end of line sequences (CR LF) as two bytes even when the file number has been opened in text mode.

#### 8.6.3.11 flush

    include std/io.e
    namespace io
    public procedure flush(file_number fn)

forces writing any buffered data to an open file or device.

##### Parameters:

1. `fn` : an integer, the handle to the file or device to close.

##### Errors:

The target file or device must be open.

##### Comments:

When you write data to a file, Euphoria normally stores the data in a memory buffer until a large enough chunk of data has accumulated. This large chunk can then be written to disk very efficiently. Sometimes you may want to force, or flush, all data out immediately, even if the memory buffer is not full. To do this you must call `flush(fn)`, where fn is the file number of a file open for writing or appending.

When a file is closed, (see `close`), all buffered data is flushed out. When a program terminates, all open files are flushed and closed automatically. Use `flush` when another process may need to see all of the data written so far, but you are not ready to close the file yet. `flush` is also used in crash routines, where files may not be closed in the cleanest possible way.

##### Example 1:

    f = open("file.log", "w")
    puts(f, "Record#1\n")
    puts(STDOUT, "Press Enter when ready\n")

    flush(f)  -- This forces "Record #1" into "file.log" on disk.
              -- Without this, "file.log" will appear to have
              -- 0 characters when we stop for keyboard input.

    s = gets(0) -- wait for keyboard input

##### See Also:

close, crash_routine

#### 8.6.3.12 lock_file

    include std/io.e
    namespace io
    public function lock_file(file_number fn, lock_type t, byte_range r = {})

locks a file so access is restricted.

##### Parameters:

1. `fn` : an integer, the handle to the file or device to (partially) lock.
2. `t` : an integer which defines the kind of lock to apply.
3. `r` : a sequence, defining a section of the file to be locked, or `{}` for the whole file (the default).

##### Returns:

An integer, 0 on failure, 1 on success.

##### Errors:

The target file or device must be open.

##### Comments:

When multiple processes can simultaneously access a file, some kind of locking mechanism may be needed to avoid mangling the contents of the file, or causing erroneous data to be read from the file.

`lock_file` attempts to place a lock on an open file, `fn`, to stop other processes from using the file while your program is reading it or writing it.

There are two types of locks that you can request using the `t` parameter. Ask for a shared lock when you intend to read a file, and you want to temporarily block other processes from writing it. Ask for an exclusive lock when you intend to write to a file and you want to temporarily block other processes from reading or writing it. It is ok for many processes to simultaneously have shared locks on the same file, but only one process can have an exclusive lock, and that can happen only when no other process has any kind of lock on the file. `io.e` contains the following declarations:

    public enum
        LOCK_SHARED,
        LOCK_EXCLUSIVE

On /Windows you can lock a specified portion of a file using the `r` parameter. `r` is a sequence of the form: `{first_byte, last_byte}`. It indicates the first byte and last byte in the file, that the lock applies to. Specify the empty sequence `{}`, if you want to lock the whole file, or don't specify it at all, as this is the default. In the current release for Unix, locks always apply to the whole file, and you should use this default value.

`lock_file` does not wait for other processes to relinquish their locks. You may have to call it repeatedly, before the lock request is granted.

On Unix, these locks are called advisory locks, which means they are not enforced by the operating system. It is up to the processes that use a particular file to cooperate with each other. A process can access a file without first obtaining a lock on it. On Windows locks are enforced by the operating system.

##### Example 1:

    include std/io.e
    integer v
    atom t
    v = open("visitor_log", "a")  -- open for append
    t = time()
    while not lock_file(v, LOCK_EXCLUSIVE, {}) do
        if time() > t + 60 then
            puts(STDOUT, "One minute already ... I can't wait forever!\n")
            abort(1)
        end if
        sleep(5) -- let other processes run
    end while
    puts(v, "Yet another visitor\n")
    unlock_file(v, {})
    close(v)

##### See Also:

unlock_file

#### 8.6.3.13 unlock_file

    include std/io.e
    namespace io
    public procedure unlock_file(file_number fn, byte_range r = {})

unlock (a portion of) an open file.

##### Parameters:

1. `fn` : an integer, the handle to the file or device to (partially) lock.
2. `r` : a sequence, defining a section of the file to be locked, or `{}` for the whole file (the default).

##### Errors:

The target file or device must be open.

##### Comments:

You must have previously locked the file using `lock_file`. On Windows you can unlock a range of bytes within a file by specifying the `r` as `{first_byte, last_byte}`. The same range of bytes must have been locked by a previous call to lock_file. On Unix you can currently only lock or unlock an entire file. `r` should be `{}` when you want to unlock an entire file. On Unix, `r` must always be `{}`, which is the default.

You should unlock a file as soon as possible so other processes can use it.

Any files that you have locked, will automatically be unlocked when your program terminates.

##### See Also:

lock_file

### 8.6.4 File Reading and Writing

#### 8.6.4.1 read_lines

    include std/io.e
    namespace io
    public function read_lines(object file)

reads the contents of a file as a sequence of lines.

##### Parameters:

`file` : an object, either a file path or the handle to an open file. If this is an empty string, STDIN (the console) is used.

##### Returns:

-1 on error or a sequence, made of lines from the file, as gets could read them.

##### Comments:

If `file` was a sequence, the file will be closed on completion. Otherwise, it will remain open, but at end of file.

##### Example 1:

    data = read_lines("my_file.txt")
    -- data contains the entire contents of ##my_file.txt##, 1 sequence per line:
    -- {"Line 1", "Line 2", "Line 3"}

##### Example 2:

    fh = open("my_file.txt", "r")
    data = read_lines(fh)
    close(fh)

    -- data contains the entire contents of ##my_file.txt##, 1 sequence per line:
    -- {"Line 1", "Line 2", "Line 3"}

##### See Also:

gets, write_lines, read_file

#### 8.6.4.2 process_lines

    include std/io.e
    namespace io
    public function process_lines(object file, integer proc, object user_data = 0)

processes the contents of a file, one line at a time.

##### Parameters:

1. `file` : an object. Either a file path or the handle to an open file. An empty string signifies `STDIN` -- the console keyboard.
2. `proc` : an integer. The routine_id of a function that will process the line.
3. `user_data` : on object. This is passed untouched to `proc` for each line.

##### Returns:

An object. If 0 then all the file was processed successfully. Anything else means that something went wrong and this is whatever value was returned by `proc`.

##### Comments:

- The function `proc` must accept three parameters:
  - A sequence: The line to process. It will not contain an end-of-line character.
  - An integer: The line number.
  - An object : This is the `user_data` that was passed to `process_lines`.
- If `file` was a sequence, the file will be closed on completion. Otherwise, it will remain open, and be positioned where ever reading stopped.

##### Example 1:

    -- Format each supplied line according to the format pattern supplied as well.
    function show(sequence aLine, integer line_no, object data)
      writefln( data[1], {line_no, aLine})
      if data[2] > 0 and line_no = data[2] then
      	return 1
      else
      	return 0
      end if
    end function
    -- Show the first 20 lines.
    process_lines("sample.txt", routine_id("show"), {"[1z:4] : [2]", 20})

##### See Also:

gets, read_lines, read_file

#### 8.6.4.3 write_lines

    include std/io.e
    namespace io
    public function write_lines(object file, sequence lines)

write a sequence of lines to a file.

##### Parameters:

1. `file` : an object, either a file path or the handle to an open file.
2. `lines` : the sequence of lines to write

##### Returns:

An integer, 1 on success, -1 on failure.

##### Errors:

If puts cannot write some line of text, a runtime error will occur.

##### Comments:

If `file` was a sequence, the file will be closed on completion. Otherwise, it will remain open, but at end of file.

Whatever integer the lines in `lines` holds will be truncated to its 8 lowest bits so as to fall in the 0..255 range.

##### Example 1:

    if write_lines("data.txt", {"This is important data", "Goodbye"}) != -1 then
        puts(STDERR, "Failed to write data\n")
    end if

##### See Also:

read_lines, write_file, puts

#### 8.6.4.4 append_lines

    include std/io.e
    namespace io
    public function append_lines(sequence file, sequence lines)

appends a sequence of lines to a file.

##### Parameters:

1. `file` : an object, either a file path or the handle to an open file.
2. `lines` : the sequence of lines to write

##### Returns:

An integer, 1 on success, -1 on failure.

##### Errors:

If puts cannot write some line of text, a runtime error will occur.

##### Comments:

`file` is opened, written to and then closed.

##### Example 1:

    if append_lines("data.txt", {"This is important data", "Goodbye"}) != -1 then
        puts(STDERR, "Failed to append data\n")
    end if

##### See Also:

write_lines, puts

#### 8.6.4.5 BINARY_MODE

    include std/io.e
    namespace io
    public enum BINARY_MODE

#### 8.6.4.6 TEXT_MODE

    include std/io.e
    namespace io
    public enum TEXT_MODE

#### 8.6.4.7 UNIX_TEXT

    include std/io.e
    namespace io
    public enum UNIX_TEXT

#### 8.6.4.8 DOS_TEXT

    include std/io.e
    namespace io
    public enum DOS_TEXT

#### 8.6.4.9 read_file

    include std/io.e
    namespace io
    public function read_file(object file, integer as_text = BINARY_MODE)

reads the contents of a file as a single sequence of bytes.

##### Parameters:

1. `file` : an object, either a file path or the handle to an open file.
2. `as_text` : integer, `BINARY_MODE` (the default) assumes binary mode that causes every byte to be read in, and `TEXT_MODE` assumes text mode that ensures that lines end with just a Control+J (NewLine) character, and the first byte value of 26 (Control+Z) is interpreted as End-Of-File.

##### Returns:

A sequence, holding the entire file.

Comments

- When using `BINARY_MODE`, each byte in the file is returned as an element in the return sequence.
- When not using `BINARY_MODE`, the file will be interpreted as a text file. This means that all line endings will be transformed to a single `0x0A` character and the first `0x1A` character (Control+Z) will indicate the end of file (all data after this will not be returned to the caller.)

##### Example 1:

    data = read_file("my_file.txt")
    -- data contains the entire contents of ##my_file.txt##

##### Example 2:

    fh = open("my_file.txt", "r")
    data = read_file(fh)
    close(fh)

    -- data contains the entire contents of ##my_file.txt##

##### See Also:

write_file, read_lines

#### 8.6.4.10 write_file

    include std/io.e
    namespace io
    public function write_file(object file, sequence data, integer as_text = BINARY_MODE)

write a sequence of bytes to a file.

##### Parameters:

1. `file` : an object, either a file path or the handle to an open file.
2. `data` : the sequence of bytes to write
3. `as_text` : integer
   - `BINARY_MODE` (the default) assumes binary mode that causes every byte to be written out as is,
   - `TEXT_MODE` assumes text mode that causes a NewLine to be written out according to the operating system's end of line convention. On Unix this is Control+J and on Windows this is the pair `{Ctrl-L, Ctrl-J}`.
   - `UNIX_TEXT` ensures that lines are written out with Unix style line endings (Control+J).
   - `DOS_TEXT` ensures that lines are written out with Windows style line endings `{Ctrl-L, Ctrl-J}`.

##### Returns:

An integer, 1 on success, -1 on failure.

##### Errors:

If puts cannot write `data`, a runtime error will occur.

##### Comments:

- When `file` is a file handle, the file is not closed after writing is finished. When `file` is a file name, it is opened, written to and then closed.
- Note that when writing the file in ony of the text modes, the file is truncated at the first Control+Z character in the input data.

##### Example 1:

    if write_file("data.txt", "This is important data\nGoodbye") = -1 then
        puts(STDERR, "Failed to write data\n")
    end if

##### See Also:

read_file, write_lines

#### 8.6.4.11 writef

    include std/io.e
    namespace io
    public procedure writef(object fm, object data = {}, object fn = 1, object data_not_string = 0)

writes formatted text to a file.

##### Parameters:

There are two ways to pass arguments to this function:

1. Traditional way with first arg being a file handle.
   1. : integer, The file handle.
   2. : sequence, The format pattern.
   3. : object, The data that will be formatted.
   4. `data_not_string`: object, If not 0 then the `data` is not a string. By default this is 0 meaning that `data` could be a single string.

1. Alternative way with first argument being the format pattern.
   1. : sequence, Format pattern.
   2. : sequence, The data that will be formatted,
   3. : object, The file to receive the formatted output. Default is to the STDOUT device (console).
   4. `data_not_string`: object, If not 0 then the `data` is not a string. By default this is 0 meaning that `data` could be a single string.

##### Comments:

- With the traditional arguments, the first argument must be an integer file handle.
- With the alternative arguments, the thrid argument can be a file name string, in which case it is opened for output, written to and then closed.
- With the alternative arguments, the third argument can be a two-element sequence containing a file name string and an output type (`"a"` for append, `"w"` for write), in which case it is opened accordingly, written to and then closed.
- With the alternative arguments, the third argument can a file handle, in which case it is written to only
- The format pattern uses the formatting codes defined in text:format.
- When the data to be formatted is a single text string, it does not have to be enclosed in braces,

##### Example 1:

    -- To console
    writef("Today is [4], [u2:3] [3:02], [1:4].",
           {Year, MonthName, Day, DayName})
    -- To "sample.txt"
    writef("Today is [4], [u2:3] [3:02], [1:4].",
           {Year, MonthName, Day, DayName}, "sample.txt")
    -- To "sample.dat"
    integer dat = open("sample.dat", "w")
    writef("Today is [4], [u2:3] [3:02], [1:4].",
           {Year, MonthName, Day, DayName}, dat)
    -- Appended to "sample.log"
    writef("Today is [4], [u2:3] [3:02], [1:4].",
           {Year, MonthName, Day, DayName}, {"sample.log", "a"})
    -- Simple message to console
    writef("A message")
    -- Another console message
    writef(STDERR, "This is a []", "message")
    -- Outputs two numbers
    writef(STDERR, "First [], second []", {65, 100}, 1)
         -- Note that {65, 100} is also "Ad"

##### See Also:

text:format, writefln, write_lines

#### 8.6.4.12 writefln

    include std/io.e
    namespace io
    public procedure writefln(object fm, object data = {}, object fn = 1,
            object data_not_string = 0)

writes formatted text to a file, ensuring that a new line is also output.

##### Parameters:

1. `fm` : sequence, Format pattern.
2. `data` : sequence, The data that will be formatted,
3. `fn` : object, The file to receive the formatted output. Default is to the `STDOUT` device (console).
4. `data_not_string`: object, If not 0 then the `data` is not a string. By default this is 0 meaning that `data` could be a single string.

##### Comments:

- This is the same as writef, except that it always adds a New Line to the output.
- When `fn` is a file name string, it is opened for output, written to and then closed.
- When `fn` is a two-element sequence containing a file name string and an output type (`"a"` for append, `"w"` for write), it is opened accordingly, written to and then closed.
- When `fn` is a file handle, it is written to only
- The `fm` uses the formatting codes defined in text:format.

##### Example 1:

    -- To console
    writefln("Today is [4], [u2:3] [3:02], [1:4].",
             {Year, MonthName, Day, DayName})
    -- To "sample.txt"
    writefln("Today is [4], [u2:3] [3:02], [1:4].",
             {Year, MonthName, Day, DayName}, "sample.txt")
    -- Appended to "sample.log"
    writefln("Today is [4], [u2:3] [3:02], [1:4].",
             {Year, MonthName, Day, DayName}, {"sample.log", "a"})

##### See Also:

text:format, writef, write_lines

| Up |  |  | TOC | Index
<< 7 Included Tools | < 8.5 File System | Up: 8 API Reference | 8.7 Operating System Helpers > | 9 Release Notes >>