@capacitor/filesystem
The Filesystem API provides a NodeJS-like API for working with files on the device.
Install
npm install @capacitor/filesystem@latest-7
npx cap sync
Apple Privacy Manifest Requirements
Apple mandates that app developers now specify approved reasons for API usage to enhance user privacy. By May 1st, 2024, it's required to include these reasons when submitting apps to the App Store Connect.
When using this specific plugin in your app, you must create a PrivacyInfo.xcprivacy file in /ios/App or use the VS Code Extension to generate it, specifying the usage reasons.
For detailed steps on how to do this, please see the Capacitor Docs.
For this plugin, the required dictionary key is NSPrivacyAccessedAPICategoryFileTimestamp and the recommended reason is C617.1.
Example PrivacyInfo.xcprivacy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<!-- Add this dict entry to the array if the PrivacyInfo file already exists -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>
Migrating from downloadFile to File Transfer plugin
As of version 7.1.0, the downloadFile functionality in the Filesystem plugin has been deprecated in favor of the new @capacitor/file-transfer plugin.
Installing the File Transfer plugin
npm install @capacitor/file-transfer@latest-7
npx cap sync
Migration example
Before (using Filesystem plugin):
import { Filesystem, Directory } from '@capacitor/filesystem';
await Filesystem.downloadFile({
url: 'https://example.com/file.pdf',
path: 'downloaded-file.pdf',
directory: Directory.Documents,
progress: true
});
// Progress events
Filesystem.addListener('progress', (progress) => {
console.log(`Downloaded ${progress.bytes} of ${progress.contentLength}`);
});
After (using File Transfer plugin):
import { FileTransfer } from '@capacitor/file-transfer';
import { Filesystem, Directory } from '@capacitor/filesystem';
// First get the full file path using Filesystem
const fileInfo = await Filesystem.getUri({
directory: Directory.Documents,
path: 'downloaded-file.pdf'
});
// Then use the FileTransfer plugin to download
await FileTransfer.downloadFile({
url: 'https://example.com/file.pdf',
path: fileInfo.uri,
progress: true
});
// Progress events
FileTransfer.addListener('progress', (progress) => {
console.log(`Downloaded ${progress.bytes} of ${progress.contentLength}`);
});
The File Transfer plugin offers improved reliability, better error handling with specific error codes, and also adds upload functionality.
iOS
To have files appear in the Files app, you must also set the following keys to YES in Info.plist:
UIFileSharingEnabled(Application supports iTunes file sharing)LSSupportsOpeningDocumentsInPlace(Supports opening documents in place)
Read about Configuring iOS for help.
Android
If using Directory.Documents or Directory.ExternalStorage, in Android 10 and older, this API requires the following permissions be added to your AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Read about Setting Permissions in the Android Guide for more information on setting Android permissions.
Note that Directory.ExternalStorage is only available on Android 9 or older and Directory.Documents only allows to access the files/folders created by your app on Android on Android 11 and newer.
Working with large files may require you to add android:largeHeap="true" to the <application> tag in AndroidManifest.xml.
Understanding Directories and Files
iOS and Android have additional layers of separation between files, such as special directories that are backed up to the Cloud, or ones for storing Documents. The Filesystem API offers a simple way to scope each operation to a specific special directory on the device.
Additionally, the Filesystem API supports using full file:// paths, or reading content:// files on Android. Simply leave out the directory param to use a full file path.
Example
import { Filesystem, Directory, Encoding } from "@capacitor/filesystem";
const writeSecretFile = async () => {
await Filesystem.writeFile({
path: "secrets/text.txt",
data: "This is a test",
directory: Directory.Documents,
encoding: Encoding.UTF8,
});
};
const readSecretFile = async () => {
const contents = await Filesystem.readFile({
path: "secrets/text.txt",
directory: Directory.Documents,
encoding: Encoding.UTF8,
});
console.log("secrets:", contents);
};
const deleteSecretFile = async () => {
await Filesystem.deleteFile({
path: "secrets/text.txt",
directory: Directory.Documents,
});
};
const readFilePath = async () => {
// Here's an example of reading a file with a full file path. Use this to
// read binary data (base64 encoded) from plugins that return File URIs, such as
// the Camera.
const contents = await Filesystem.readFile({
path: "file:///var/mobile/Containers/Data/Application/22A433FD-D82D-4989-8BE6-9FC49DEA20BB/Documents/text.txt",
});
console.log("data:", contents);
};
API
For list of existing error codes, see Errors.
checkPermissions()
checkPermissions() => Promise<PermissionStatus>
Check read/write permissions.
Required on Android, only when using Directory.Documents or
Directory.ExternalStorage.
Returns:
Promise<PermissionStatus>
Since: 1.0.0
requestPermissions()
requestPermissions() => Promise<PermissionStatus>
Request read/write permissions.
Required on Android, only when using Directory.Documents or
Directory.ExternalStorage.
Returns:
Promise<PermissionStatus>
Since: 1.0.0
readFile(...)
readFile(options: ReadFileOptions) => Promise<ReadFileResult>
Read a file from disk
| Param | Type |
|---|---|
options | |
Returns:
Promise<ReadFileResult>
Since: 1.0.0
readFileInChunks(...)
readFileInChunks(options: ReadFileInChunksOptions, callback: ReadFileInChunksCallback) => Promise<CallbackID>
Read a file from disk, in chunks. Native only (not available in web). Use the callback to receive each read chunk. If empty chunk is returned, it means file has been completely read.
| Param | Type |
|---|---|
options | |
callback | |
Returns: Promise<string>
Since: 7.1.0
writeFile(...)
writeFile(options: WriteFileOptions) => Promise<WriteFileResult>
Write a file to disk in the specified location on device
| Param | Type |
|---|---|
options | |
Returns:
Promise<WriteFileResult>
Since: 1.0.0
appendFile(...)
appendFile(options: AppendFileOptions) => Promise<void>
Append to a file on disk in the specified location on device
| Param | Type |
|---|---|
options | |
Since: 1.0.0
deleteFile(...)
deleteFile(options: DeleteFileOptions) => Promise<void>
Delete a file from disk
| Param | Type |
|---|---|
options | |
Since: 1.0.0
mkdir(...)
mkdir(options: MkdirOptions) => Promise<void>
Create a directory.
| Param | Type |
|---|---|
options | |
Since: 1.0.0
rmdir(...)
rmdir(options: RmdirOptions) => Promise<void>
Remove a directory
| Param | Type |
|---|---|
options | |
Since: 1.0.0
readdir(...)
readdir(options: ReaddirOptions) => Promise<ReaddirResult>
Return a list of files from the directory (not recursive)
| Param | Type |
|---|---|
options | |
Returns:
Promise<ReaddirResult>
Since: 1.0.0
getUri(...)
getUri(options: GetUriOptions) => Promise<GetUriResult>
Return full File URI for a path and directory
| Param | Type |
|---|---|
options | |
Returns:
Promise<GetUriResult>
Since: 1.0.0
stat(...)
stat(options: StatOptions) => Promise<StatResult>
Return data about a file
| Param | Type |
|---|---|
options | |
Returns:
Promise<FileInfo>
Since: 1.0.0
rename(...)
rename(options: RenameOptions) => Promise<void>
Rename a file or directory
| Param | Type |
|---|---|
options | |
Since: 1.0.0
copy(...)
copy(options: CopyOptions) => Promise<CopyResult>
Copy a file or directory
| Param | Type |
|---|---|
options | |
Returns:
Promise<CopyResult>
Since: 1.0.0
downloadFile(...)
downloadFile(options: DownloadFileOptions) => Promise<DownloadFileResult>
Perform a http request to a server and download the file to the specified destination.
This method has been deprecated since version 7.1.0. We recommend using the @capacitor/file-transfer plugin instead, in conjunction with this plugin.
| Param | Type |
|---|---|
options | |
Returns:
Promise<DownloadFileResult>
Since: 5.1.0
addListener('progress', ...)
addListener(eventName: 'progress', listenerFunc: ProgressListener) => Promise<PluginListenerHandle>
Add a listener to file download progress events.
This method has been deprecated since version 7.1.0. We recommend using the @capacitor/file-transfer plugin instead, in conjunction with this plugin.
| Param | Type |
|---|---|
eventName | 'progress' |
listenerFunc | |
Returns:
Promise<PluginListenerHandle>
Since: 5.1.0
removeAllListeners()
removeAllListeners() => Promise<void>
Remove all listeners for this plugin.
This method has been deprecated since version 7.1.0. We recommend using the @capacitor/file-transfer plugin instead, in conjunction with this plugin.
Since: 5.2.0
Interfaces
PermissionStatus
| Prop | Type |
|---|---|
publicStorage | |
ReadFileResult
| Prop | Type | Description | Since |
|---|---|---|---|
data | string | Blob | The representation of the data contained in the file Note: Blob is only available on Web. On native, the data is returned as a string. | 1.0.0 |
ReadFileOptions
| Prop | Type | Description | Since |
|---|---|---|---|
path | string | The path of the file to read | 1.0.0 |
directory | | The Directory to read the file from | 1.0.0 |
encoding | | The encoding to read the file in, if not provided, data is read as binary and returned as base64 encoded. Pass Encoding.UTF8 to read data as string | 1.0.0 |
ReadFileInChunksOptions
| Prop | Type | Description | Since |
|---|---|---|---|
chunkSize | number | Size of the chunks in bytes. | 7.1.0 |
WriteFileResult
| Prop | Type | Description | Since |
|---|---|---|---|
uri | string | The uri where the file was written into | 1.0.0 |
WriteFileOptions
| Prop | Type | Description | Default | Since |
|---|---|---|---|---|
path | string | The path of the file to write | 1.0.0 | |
data | string | Blob | The data to write Note: Blob data is only supported on Web. | 1.0.0 | |
directory | | The Directory to store the file in | 1.0.0 | |
encoding | | The encoding to write the file in. If not provided, data is written as base64 encoded. Pass Encoding.UTF8 to write data as string | 1.0.0 | |
recursive | boolean | Whether to create any missing parent directories. | false | 1.0.0 |
AppendFileOptions
| Prop | Type | Description | Since |
|---|---|---|---|
path | string | The path of the file to append | 1.0.0 |
data | string | The data to write | 1.0.0 |
directory | | The Directory to store the file in | 1.0.0 |
encoding | | The encoding to write the file in. If not provided, data is written as base64 encoded. Pass Encoding.UTF8 to write data as string | 1.0.0 |
DeleteFileOptions
| Prop | Type | Description | Since |
|---|---|---|---|
path | string | The path of the file to delete | 1.0.0 |
directory | | The Directory to delete the file from | 1.0.0 |
MkdirOptions
| Prop | Type | Description | Default | Since |
|---|---|---|---|---|
path | string | The path of the new directory | 1.0.0 | |
directory | | The Directory to make the new directory in | 1.0.0 | |
recursive | boolean | Whether to create any missing parent directories as well. | false | 1.0.0 |