# File Plugin Basics

## Overview

The File Plugin in Servoy provides server-side access to file system operations when working with browser clients and can also be used on NGDesktop for client-side file access. With the plugin, developers can handle file operations such as retrieving metadata, reading/writing text or binary data, uploading and downloading files, and performing file system operations like moving, copying, and tracking files.

For NGDesktop applications, where client-side file access is required, you can use specific features that provide access to the local file system directly. You can find [here](https://docs.servoy.com/reference/servoyextensions/browser-plugins/ngdesktop-file#ngdesktop-file-ref) relevant documentation on NGDesktop file.

More information about File Plugin can be found [here](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#file).\
More information about JSFile can be found [here](https://docs.servoy.com/reference/servoyextensions/server-plugins/file/jsfile#overview).

## Getting File Info

You can retrieve various file metadata such as the file path, size, and last modified time.

Code Example: Get File Metadata

```javascript
            var f = plugins.file.convertToJSFile('./my-file.txt');
			if (f && f.exists()) {
				application.output('is absolute: ' + f.isAbsolute());
				application.output('is dir: ' + f.isDirectory());
				application.output('is file: ' + f.isFile());
				application.output('is hidden: ' + f.isHidden());
				application.output('can read: ' + f.canRead());
				application.output('can write: ' + f.canWrite());
				application.output('last modified: ' + f.lastModified());
				application.output('name: ' + f.getName());
				application.output('path: ' + f.getPath());
				application.output('absolute path: ' + f.getAbsolutePath());
				application.output('content type: ' + f.getContentType());
				application.output('size: ' + f.size());

                application.output('modification date: ' + plugins.file.getModificationDate(f)); 

			} else {
				application.output('File/folder not found.');
			}
```

## Create File

To create a file, there should be a [JSFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file/jsfile#overview) first. Creating JSFiles can be done using the function [plugins.file.createFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#createfile-targetfile). On a JSFile there is the function [JSFile.createNewFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file/jsfile#createnewfile) to actually create the file on disk.

Here is a simple example that creates a file `helloworld.txt` in the user folder of user "servoy" in Windows:

```javascript
var f = plugins.file.createFile("C:\\users\\servoy\\helloworld.txt");
f.createNewFile();
```

Back slash in windows file paths:\
In the example above the path `C:\users\servoy\helloworld.txt` is written as `C:\\users\\servoy\\helloworld.txt` (with double back slashes). This is done because the `\` is the escape character in javascript strings.

Another option is to use `/` instead, this will work just as well:

```javascript
var f = plugins.file.createFile("C:/users/servoy/helloworld.txt");
f.createNewFile();
```

Here an example to create a file in the home directory of user "servoy" in Ubuntu:

```javascript
var f = plugins.file.createFile("/home/servoy/helloworld.txt");
f.createNewFile();
```

To do the same on a Mac:

```javascript
var f = plugins.file.createFile("/Users/servoy/helloworld.txt");
f.createNewFile();
```

OS-independent path: As can be seen in the examples above, it is not a good practice to use hardcoded paths in the code, because they don't work on every OS. It is better to use a more general approach. The file plugin has several functions to help with that: [plugins.file.getDesktopFolder](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#getdesktopfolder) and [plugins.file.getHomeFolder](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#gethomefolder).

Here is a sample that does the same as the previous examples, but it works on all the operating systems above:

```javascript
var f = plugins.file.createFile(plugins.file.getDesktopFolder() + "/helloworld.txt");
f.createNewFile();
```

## Working with Text Files

### Writing Text Files

The [plugins.file.writeTXTFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#writetxtfile-file-text_data) method is used to write content to files in text format. You can specify the file where the text will be written, the text content itself, and optionally the encoding format. By default, the system uses the operating system's default encoding, but you can override this by specifying a different encoding if needed.

Code Example: Writing Text to a File

```javascript
var file_text = "Hello world!";
var f = plugins.file.convertToJSFile(plugins.file.getDesktopFolder() + "/helloworld.txt");
plugins.file.writeTXTFile(f, file_text);
```

### Reading Text Files

Reading from a text file can be done using the [plugins.file.readTXTFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#readtxtfile-file) method.

Code Example: Reading Text from a File

```javascript
var file_text = plugins.file.readTXTFile(plugins.file.getDesktopFolder() + "/helloworld.txt");
```

Optionally the charset can be specified in the second parameter, if left out it will take the OS default (For a list of possible charsets, look [here](https://docs.oracle.com/javase/1.5.0/docs/guide/intl/encoding.doc.html)):

```javascript
var file_text = plugins.file.readTXTFile(plugins.file.getDesktopFolder() + "/helloworld.txt", "ISO8859_1");
```

If the user should choose which file to read, [plugins.file.readTXTFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#readtxtfile) can be called without parameters, then a file choose dialog will open:

```javascript
var file_text = plugins.file.readTXTFile(); 
```

{% hint style="warning" %}
**Memory Considerations**\
When working with large text files, it's important to consider memory usage, as reading large files entirely into memory could exhaust available resources. For larger files, consider processing them line by line.
{% endhint %}

When using `readTXTFile`, the entire text is written to the memory. With big text files this might be a problem, because they take a lot of memory, maybe even more than available.\
Because of this problem, using `readTXTFile` is not the best option if to read huge files. In that case it is better to use some inline java code to read the file line by line using a buffered reader. See this example:

```javascript
var file_Name = plugins.file.showFileOpenDialog();
var f = new Packages.java.io.File(file_Name);
var file_reader = new Packages.java.io.BufferedReader(new Packages.java.io.FileReader(f));
var text;
while ((text = file_reader.readLine()) != null) {
application.output(text);
// Do other stuff with the text here
}
//close the reader
file_reader.close();
```

## Working with Binary Files

### Writing Binary Files

To write binary data to a file, you can use [plugins.file.writeFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#writefile-file-data) method by passing a byte array.\
The `plugins.file.writeFile` method allows you to write binary data (such as images, PDFs, or any other file in binary format) to a file. This is useful when working with binary data from databases or other sources that need to be saved as files on the server or client-side.

Code Example: Writing Binary Data

```javascript
var file_bytes = photo; // photo is a blob column from the database
var f = plugins.file.convertToJSFile(plugins.file.getDesktopFolder() + "/photo.jpg");

// Writing binary data to the file
plugins.file.writeFile(f, file_bytes);
```

### Reading Binary Files

You can read binary files with the [plugins.file.readFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#readfile-file) method.\
The `plugins.file.readFile` method allows you to read the contents of binary files, such as images, PDFs, or any other file that contains non-text data. This method returns the binary data as a byte array, which can then be processed or stored in a database.

Code Example: Reading Binary Data

```javascript
var file_bytes = plugins.file.readFile(plugins.file.getDesktopFolder() + "/helloworld.jpg");
```

If only a part of the file has to be read, the number of bytes can be specified using the second parameter. For example if 1kB should be read:

```javascript
var file_bytes = plugins.file.readFile(plugins.file.getDesktopFolder() + "/helloworld.jpg", 1024);
```

If the user should choose which file to read, [plugins.file.readFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#readfile) can be called without parameters, then a file choose dialog will open:

```javascript
var file_bytes = plugins.file.readFile();
```

{% hint style="warning" %}
**Memory Considerations**\
When reading or writing large binary files, you must manage memory carefully to avoid heap space issues. Consider breaking large files into smaller chunks and processing them in parts.
{% endhint %}

## Working with XML Files

### Writing XML Files

In Servoy, you can write XML files using the [plugins.file.writeXMLFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#writexmlfile-file-xml_data) method. This allows you to store structured data in XML format, which is commonly used for configurations, data interchange, or documents.

Code Example: Writing XML Data to a File

```javascript
var xml_content = <hello>world</hello>;
var f = plugins.file.convertToJSFile(plugins.file.getDesktopFolder() + "/helloworld.xml");

// Writing XML data to the file
plugins.file.writeXMLFile(f, xml_content);
```

## Downloading Files / Opening a File in the Browser

Servoy allows you to trigger file downloads or open files directly in the browser. This can be done using [plugins.file.openFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#openfile-file) method.

Code Example: Downloading a File

```javascript
function onDownload(event) {
	var f = plugins.file.convertToJSFile("helloworld.txt")
	download_file(f)
}

function download_file(file)
{
	plugins.file.openFile(file);
}
```

## Uploading Files

File uploads in Servoy are handled using the [plugins.file.showFileOpenDialog](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#showfileopendialog-callbackfunction) method. Uploaded files can be processed server-side.

Code Example: Uploading Files

```javascript
 function openFile(event) {
	plugins.file.showFileOpenDialog(onOpen)
}

function onOpen(files){
	plugins.file.openFile(files[0]);
	application.output(files[0])
}
```

{% hint style="info" %}
**Default Upload Location** The `servoy.FileServerService.defaultFolder` property in `Server Plugins` section of [Servoy Admin Page](https://docs.servoy.com/deploy/server-configuration#servoy-admin-page) determines where files are uploaded by default on the server. You can change this property to suit your application's needs.
{% endhint %}

Servoy also provides dedicated UI components for file uploading, allowing more customization and flexibility in handling user uploads. These components offer features such as multiple file selection and additional styling options, making them ideal for applications with more complex file upload requirements.

* [**File Upload Component**](https://docs.servoy.com/guides/develop/application-design/ui-components/media/fileupload): This component allows users to upload individual files with a user-friendly interface. It can be customized to match the application's design and offers events like file selection and upload progress tracking.
* [**MultiFile Upload Component**](https://docs.servoy.com/guides/develop/application-design/ui-components/media/multifile-upload): This component enables users to upload multiple files at once, providing a streamlined experience for applications that require bulk file uploads. It supports multiple file selection, drag-and-drop functionality, and file size validations.

## File System Operations (Server-side)

### Listing Files

To list files in a directory, use [plugins.file.getFolderContents](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#getfoldercontents-targetfolder) method. The `plugins.file.getFolderContents` method retrieves an array of JSFile instances representing the files and directories within a specified folder. This method is useful for obtaining the list of files from a directory, and it supports various filters to narrow down the content based on file names, file types, visibility, and lock status.

Code Example: Listing Files in a Directory

```javascript
var files = plugins.file.getFolderContents('myFolder', '.txt');
		for (var i = 0; i < files.length; i++)
			application.output(files[i].getAbsolutePath());
```

### Moving Files

You can move files using the [plugins.file.moveFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#movefile-source-destination) method.\
The `plugins.file.moveFile` method allows you to move files from one location to another. You can move files based on their file names (as strings) or by using JSFile instances. The method returns true if the move is successful and false if any error occurs during the process.

Code Example: Moving Files by Name

```javascript
if (!plugins.file.moveFile('home.txt', 'home.txt.new')) {
    application.output('File move failed.');
} else {
    application.output('File moved successfully.');
}
```

Code Example: Moving Files with `JSFile` Instances

```javascript
var sourceFile = plugins.file.convertToJSFile('home.txt.new');
var destinationFile = plugins.file.convertToJSFile('home.txt');

if (!plugins.file.moveFile(sourceFile, destinationFile)) {
    application.output('File move back failed.');
} else {
    application.output('File moved back successfully.');
}
```

### Copying Files

The [plugins.file.copyFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#copyfile-source-destination) method allows you to copy files from one location to another. You can use this method to duplicate files based on file names or JSFile instances. The method returns true if the copy operation is successful, and false if any error occurs during the process.

Code Examples:\
Copying Files Based on File Names: You can copy files using their file paths as string values.

```javascript
if (!plugins.file.copyFile("home.txt", "home.txt.copy")) {
    application.output("Copy failed.");
} else {
    application.output("Copy succeeded.");
}
```

Copying Files Based on JSFile Instances: Alternatively, you can copy files by first creating JSFile objects.

```javascript
var sourceFile = plugins.file.createFile("home.txt");
var destinationFile = plugins.file.createFile("home.txt.copy2");

if (!plugins.file.copyFile(sourceFile, destinationFile)) {
    application.output("Copy failed.");
} else {
    application.output("Copy succeeded.");
}
```

### Working with Temp Files

Servoy provides the ability to create temporary files that are automatically managed and removed when the client session ends. These temp files are useful for handling data that is only needed during the session and should not persist after the solution is closed. Temp files will be created in the default temporary-file directory, using the given prefix and suffix to generate its name. Temporary files can be created using [plugins.file.createTempFile](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#createtempfile-prefix-suffix) method.

Code Example:

```javascript
var tempFile = plugins.file.createTempFile("helloworld", ".txt");
```

After executing this code, there will be a new (empty) file in the temp directory with a name like this: `helloworld1571360175321712533.txt`. The filename will be unique because of the number that is added in the middle.

### Tracking Files

The [plugins.file.trackFileForDeletion](https://docs.servoy.com/reference/servoyextensions/server-plugins/file#trackfilefordeletion-file) method in Servoy ensures that a file is automatically deleted when the client's solution is closed. This method is particularly useful for managing temporary files that should only persist during the session and should be cleaned up afterward, whether they are local or remote files.

Usage Scenario:\
If your application creates temporary files (such as log files, data exports, or reports) that are needed during the session but not afterward, this method allows you to automatically delete these files when the solution closes.

Code Example:

```javascript
var file = plugins.file.createFile("newfile.txt");

// Write some data to the file
plugins.file.writeTXTFile(file, "Temporary data for session.");

// Track the file for deletion when the client solution is closed
plugins.file.trackFileForDeletion(file);
```
