# Special i/o objects

This chapter is dedicated to special facilities which are part of the standard i/o module.

## Directory

The `Directory` class provides a facility to manipulate directories. A directory object is created either by name or without argument by considering the current working directory. Once the directory object is created, it is possible to retrieve its contents, create new directory or remove empty one.

## Reading a directory

A `Directory` object is created either by name or without argument. With no argument, the current directory is opened. When the current directory is opened, its full name is computed internally and can be retrieved with the `get-name` method.

# print the current directory const pwd (afnix:sio:Directory) println (pwd:get-name)

Once the directory object is opened, it is possible to list its contents. The `get-list` method returns the full contents of the directory object. The `get-files` method returns a list of files in this directory. The `get-subdirs` method returns a list of sub directories in this directory.

# print a list of files const pwd (afnix:sio:Directory) const lsf (d:get-files) for (name) (lsf) (println name)

## Creating and removing directories

The `mkdir` and `rmdir` methods can be used to create or remove a directory. Both methods take a string argument and construct a full path name from the directory name and the argument. This approach has the advantage of being file system independent. If the directory already exists, the `mkdir` methods succeeds. The `rmdir` method requires the directory to be empty.

const tmp (afnix:sio:Directory (afnix:sio:absolute-path "tmp")) const exp (tmp:mkdir "examples") const lsf (exp:get-files) println (lsf:length) tmp:rmdir "examples"

The function `absolute-path` constructs an absolute path name from the argument list. If relative path needs to be constructed, the function `relative-path` might be used instead.

## Logtee

The `Logtee` class is a message logger facility associated with an output stream. When a message is added to the logger object, the message is also sent to the output stream, depending on the controlling flags. The name "logtee" comes from the contraction of "logger" and "tee". One particularity of the class is that without a stream, the class behaves like a regular logger.

## Creating a logger

The `Logtee` default constructor creates a standard logger object without an output stream. The instance can also be created by size or with an output stream or both. A third method can also attach an information string.

# create a logger with the interpreter stream const log (Logtee (interp:get-output-stream)) assert true (logger-p log)

## Adding messages

The process of adding messages is similar to the regular logger. The only difference is that the message is placed on the output stream if a control flag is set and the message level is less or equal the report level. In the other word, the control flag controls the message display -- the tee operation -- while the report level filters some of the messages.

log:add 2 "a level 2 message"

The `set-tee` method sets the control flag. The `set-report-level` method sets the report level. Note that the `set-report-level` and its associated `get-report-level` method is part of the base `Logger` class.