This page shows how to list, upload, download, rename and delete the files of a Staubli CS8 or CS9 controller from a PC, with `controller.File`. The same code works on a real controller (FTP) and on the emulator of Staubli Robotics Suite (folder of its `.controller` file): see [Files overview](/staubli/documentation/files-overview) for the connection.

## List the files

`GetListing(path)` returns the files and folders of a folder. `GetFileInfo(path)` returns one item, or `null` when it does not exist.

**C# : FilesList**
```csharp
using UnderAutomation.Staubli;
using UnderAutomation.Staubli.Files;

public class FilesList
{
    static void Main()
    {
        var parameters = new ConnectionParameters("192.168.0.254");
        parameters.File.Enable = true;
        var controller = new StaubliController();
        controller.Connect(parameters);

        /**/
        // Content of a folder of the controller
        foreach (FileItem item in controller.File.GetListing("/usr/usrapp"))
            Console.WriteLine($"{item.FullName} {item.Type} {item.Size} bytes {item.Modified}");

        // One file or folder, null when it does not exist
        FileItem project = controller.File.GetFileInfo("/usr/usrapp/myApp/myApp.pjx");

        bool fileExists = controller.File.FileExists("/usr/usrapp/myApp/myApp.pjx");
        bool folderExists = controller.File.DirectoryExists("/usr/usrapp/myApp");
        /**/

        controller.Disconnect();
    }
}
```

**Python : FilesList**
```python
from underautomation.staubli.staubli_controller import StaubliController
from underautomation.staubli.connection_parameters import ConnectionParameters

parameters = ConnectionParameters("192.168.0.254")
parameters.file.enable = True
controller = StaubliController()
controller.connect(parameters)

##
# Content of a folder of the controller
for item in controller.file.get_listing("/usr/usrapp"):
    print(item.full_name, item.type, item.size, "bytes", item.modified)

# One file or folder, None when it does not exist
project = controller.file.get_file_info("/usr/usrapp/myApp/myApp.pjx")

file_exists = controller.file.file_exists("/usr/usrapp/myApp/myApp.pjx")
folder_exists = controller.file.directory_exists("/usr/usrapp/myApp")
##

controller.disconnect()
```

| Property   | Meaning                                                                |
| ---------- | ---------------------------------------------------------------------- |
| `Name`     | Name, without the path                                                 |
| `FullName` | Full path on the controller, for example `/usr/usrapp/myApp/myApp.pjx` |
| `Type`     | `FileItemType.File` or `FileItemType.Directory`                        |
| `Size`     | Size in bytes, `0` for a folder                                        |
| `Modified` | Date of the last change. With the emulator, local time of the PC       |

## Upload and download

**C# : FilesTransfer**
```csharp
using System.Text;
using UnderAutomation.Staubli;

public class FilesTransfer
{
    static void Main()
    {
        var parameters = new ConnectionParameters("192.168.0.254");
        parameters.File.Enable = true;
        var controller = new StaubliController();
        controller.Connect(parameters);

        /**/
        // Upload a local file. createRemoteDir: true creates the folder on the controller when it does not exist.
        controller.File.UploadFileToController(@"C:\Data\points.dat", "/usr/usrapp/myApp/points.dat", true,
            progress => Console.WriteLine($"{progress:0}%"));

        // Upload bytes
        controller.File.UploadBytesToController(Encoding.ASCII.GetBytes("1;2;3"), "/usr/usrapp/myApp/data.txt");

        // Download to a local file (replaced when it exists)
        controller.File.DownloadFileFromController(@"C:\Backup\myApp.pjx", "/usr/usrapp/myApp/myApp.pjx");

        // Download the content
        byte[] content = controller.File.DownloadBytesFromController("/usr/usrapp/myApp/data.txt");
        Console.WriteLine(Encoding.ASCII.GetString(content));
        /**/

        controller.Disconnect();
    }
}
```

**Python : FilesTransfer**
```python
from underautomation.staubli.staubli_controller import StaubliController
from underautomation.staubli.connection_parameters import ConnectionParameters

parameters = ConnectionParameters("192.168.0.254")
parameters.file.enable = True
controller = StaubliController()
controller.connect(parameters)

##
# Upload a local file. The third argument True creates the folder on the controller when it does not exist.
controller.file.upload_file_to_controller(r"C:\Data\points.dat", "/usr/usrapp/myApp/points.dat", True,
                                          lambda progress: print(f"{progress:.0f}%"))

# Upload bytes
controller.file.upload_bytes_to_controller(b"1;2;3", "/usr/usrapp/myApp/data.txt")

# Download to a local file (replaced when it exists)
controller.file.download_file_from_controller(r"C:\Backup\myApp.pjx", "/usr/usrapp/myApp/myApp.pjx")

# Download the content
content = controller.file.download_bytes_from_controller("/usr/usrapp/myApp/data.txt")
print(bytes(content).decode("ascii"))
##

controller.disconnect()
```

### Upload

- `UploadFileToController(localPath, remotePath)` sends a local file.
- `UploadBytesToController(data, remotePath)` and `UploadStreamToController(stream, remotePath)` send data from memory or a stream.
- The file of the controller is replaced when it exists. With `createRemoteDir` set to `true`, its folder is created when it does not exist.

### Download

- `DownloadFileFromController(localPath, remotePath)` writes a local file. The local file is replaced, and its folder is created.
- `DownloadBytesFromController(remotePath)` returns the content, `DownloadStreamFromController(stream, remotePath)` writes it to a stream.
- A file that does not exist on the controller throws a `FileException`. No local file is created.

The optional `progress` argument receives the percentage of the transfer, from 0 to 100.

## Folders, rename and delete

**C# : FilesManage**
```csharp
using UnderAutomation.Staubli;

public class FilesManage
{
    static void Main()
    {
        var parameters = new ConnectionParameters("192.168.0.254");
        parameters.File.Enable = true;
        var controller = new StaubliController();
        controller.Connect(parameters);

        /**/
        // Create a folder, with its parent folders
        controller.File.CreateDirectory("/usr/usrapp/myApp/backup");

        // Rename or move a file or a folder
        controller.File.Rename("/usr/usrapp/myApp/data.txt", "/usr/usrapp/myApp/backup/data.txt");

        // Delete a file
        controller.File.DeleteFile("/usr/usrapp/myApp/backup/data.txt");

        // Delete a folder and all its content
        controller.File.DeleteDirectory("/usr/usrapp/myApp/backup");
        /**/

        controller.Disconnect();
    }
}
```

**Python : FilesManage**
```python
from underautomation.staubli.staubli_controller import StaubliController
from underautomation.staubli.connection_parameters import ConnectionParameters

parameters = ConnectionParameters("192.168.0.254")
parameters.file.enable = True
controller = StaubliController()
controller.connect(parameters)

##
# Create a folder, with its parent folders
controller.file.create_directory("/usr/usrapp/myApp/backup")

# Rename or move a file or a folder
controller.file.rename("/usr/usrapp/myApp/data.txt", "/usr/usrapp/myApp/backup/data.txt")

# Delete a file
controller.file.delete_file("/usr/usrapp/myApp/backup/data.txt")

# Delete a folder and all its content
controller.file.delete_directory("/usr/usrapp/myApp/backup")
##

controller.disconnect()
```

- `CreateDirectory` creates the parent folders too. Nothing is done when the folder exists.
- `Rename` renames or moves a file or a folder.
- `DeleteFile` and `DeleteDirectory` throw a `FileException` when the item does not exist. `DeleteDirectory` deletes all the content.

To send a complete VAL 3 application, see [Send a VAL 3 application](/staubli/documentation/files-applications).

## Asynchronous methods

Each method has an asynchronous version, with an optional `CancellationToken`: `GetListingAsync`, `UploadFileToControllerAsync`, `DownloadBytesFromControllerAsync`... They are not available on .NET Framework 3.5 and 4.0.

**C# : FilesAsync**
```csharp
using UnderAutomation.Staubli;
using UnderAutomation.Staubli.Files;

public class FilesAsync
{
    static async Task Main()
    {
        var parameters = new ConnectionParameters("192.168.0.254");
        parameters.File.Enable = true;
        var controller = new StaubliController();
        controller.Connect(parameters);

        /**/
        using var cancellation = new CancellationTokenSource(TimeSpan.FromMinutes(1));

        FileItem[] items = await controller.File.GetListingAsync("/usr/usrapp", cancellation.Token);

        await controller.File.UploadFileToControllerAsync(@"C:\Data\points.dat", "/usr/usrapp/myApp/points.dat",
            cancellationToken: cancellation.Token);

        byte[] content = await controller.File.DownloadBytesFromControllerAsync("/usr/usrapp/myApp/points.dat",
            cancellationToken: cancellation.Token);
        /**/

        controller.Disconnect();
    }
}
```

## Reference

**Members of Files.FileItem**
```csharp
public class FileItem {
    // Full path of the file or folder on the controller (for example "/usr/usrapp/myApp/myApp.pjx")
    public string FullName { get; }

    // Date and time of the last modification, as given by the controller. With a controller emulated by Staubli Robotics Suite, local time of the computer.
    public DateTime Modified { get; }

    // Name of the file or folder, without its path (for example "myApp.pjx")
    public string Name { get; }

    // Size of the file in bytes. 0 for a folder, and 0 when the controller does not give the size.
    public long Size { get; }

    public override string ToString()

    // File or folder
    public FileItemType Type { get; }
}
```

**Members of Files.FileItemType**
```csharp
public enum FileItemType {
    // A folder
    Directory = 1

    // A file
    File = 0
}
```