# File handling

The File entity encapsulates all information of a dataset. File entities keep some general information such as creation time and date, format version etc. It is the entry-point to a NIX file.

## File modes

A NIX file can be opened in one of three modes:

1. `nixio.FileMode.Overwrite` Used for creating a new file or overwriting any content in an existing one!

2. `nixio.FileMode.ReadWrite` Opens a file if it exists or otherwise creates a new one. Does not overwrite existing content.

3. `nixio.FileMode.ReadOnly` Opens an existing file. The content can not be changed. Will raise an error when the provided path is invalid (e.g. the file does not exist).

## Creating a new file

Creating a new nix file with `nixio.FileMode.Overwite` or `nixio.FileMode.ReadWrite` (`example code`

    import nixio
    import datetime as dt

    file_name = 'file_create_example.nix'

    # create a new file overwriting any existing content
    nixfile = nixio.File.open(file_name, nixio.FileMode.Overwrite)
    print("Nix file: %s\n\tformat: %s\n\tversion: %s\n\tcreated at: %s" % (file_name, nixfile.format, nixfile.version,
                                                                           str(dt.datetime.fromtimestamp(nixfile.created_at))))
    nixfile.close()

As mentioned above, using `nixio.FileMode.Overwrite` will destroy any existing content of the file. By default, if the `FileMode` flag is not specified, a file is opened in the `FileMode.ReadWrite` mode.

In this tutorial files will always have the extension `*.nix`. This is not specified in the library and you are free to use any file extension.

## Opening existing files

Use `nixio.FileMode.ReadWrite` or `nixio.FileMode.ReadOnly` to open an existing file to work with the data. If you want to overwrite any existing content in order to replace the file use `nixio.FileMode.Overwite`.

In `ReadOnly` mode, you cannot change the file content:

    # re-open file for read-only access
    nixfile = nixio.File.open(file_name, nixio.FileMode.ReadOnly)

    # this command will fail putting out an error
    try:
        nixfile.create_block("test block", "test")
    except ValueError:
        print("Error caught: cannot create a new group in nix.FileMode.ReadOnly mode")

    nixfile.close()

In order to change the file content the file needs to be opened in `ReadWrite` mode:

    # re-open for read-write access, creating new entities will work
    nixfile = nixio.File.open(file_name, nixio.FileMode.ReadWrite)
    nixfile.create_block("test block", "test")
    nixfile.close()

Trying to open an non-existing file in `ReadOnly` mode will lead to an error!

    nonexistingfilename = "nonexistingfile.nix"

    try:
        nixfile = nixio.File.open(nonexistingfilename, nixio.FileMode.ReadOnly)
    except RuntimeError as e:
        print("Error caught: %s" % str(e))
        print("One cannot open a file, that is not existing and forbidding the library to write it.")

## Enabling compression

By default, data stored inside a NIX file will not be compressed. You can switch on compression during file opening.

    nixfile = nixio.File.open(file_name, mode=nixio.FileMode.Overwrite, compression=nixio.Compression.DeflateNormal)
    nixfile.close()

Compression is handled transparently by the hdf5-library, no further user interaction is required. Compression reduces reading and writing performance. You can choose to switch off compression on individual DataArrays by passing the `nixio.Compression.No` flag at the time of creation.