跳到主要内容
版本:v8

@capacitor/filesystem

Filesystem API 提供了类似 NodeJS 的 API,用于在设备上处理文件。

安装

npm install @capacitor/filesystem
npx cap sync

Apple 隐私清单要求

Apple 现在要求应用开发者指定 API 使用的原因以增强用户隐私。在 2024 年 5 月 1 日前,提交应用到 App Store Connect 时必须包含这些原因。

当你在应用中使用此特定插件时,必须在 /ios/App 目录下创建一个 PrivacyInfo.xcprivacy 文件,或使用 VS Code 扩展来生成它,并指定使用原因。

关于如何执行此操作的详细步骤,请参阅 Capacitor 文档

对于此插件,所需的字典键是 NSPrivacyAccessedAPICategoryFileTimestamp,推荐的原因是 C617.1

隐私清单文件示例

<?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>
<!-- 如果 PrivacyInfo 文件已存在,请将此字典条目添加到数组中 -->
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>

从 downloadFile 迁移至 File Transfer 插件

自版本 7.1.0 起,Filesystem 插件中的 downloadFile 功能已被弃用,转而推荐使用新的 @capacitor/file-transfer 插件。

安装 File Transfer 插件

npm install @capacitor/file-transfer
npx cap sync

迁移示例

迁移前(使用 Filesystem 插件):

import { Filesystem, Directory } from '@capacitor/filesystem';

await Filesystem.downloadFile({
url: 'https://example.com/file.pdf',
path: 'downloaded-file.pdf',
directory: Directory.Documents,
progress: true
});

// 进度事件
Filesystem.addListener('progress', (progress) => {
console.log(`Downloaded ${progress.bytes} of ${progress.contentLength}`);
});

迁移后(使用 File Transfer 插件):

import { FileTransfer } from '@capacitor/file-transfer';
import { Filesystem, Directory } from '@capacitor/filesystem';

// 首先使用 Filesystem 获取完整的文件路径
const fileInfo = await Filesystem.getUri({
directory: Directory.Documents,
path: 'downloaded-file.pdf'
});

// 然后使用 FileTransfer 插件进行下载
await FileTransfer.downloadFile({
url: 'https://example.com/file.pdf',
path: fileInfo.uri,
progress: true
});

// 进度事件
FileTransfer.addListener('progress', (progress) => {
console.log(`Downloaded ${progress.bytes} of ${progress.contentLength}`);
});

File Transfer 插件提供了更高的可靠性、更好的错误处理(包含特定的错误码),并增加了上传功能。

iOS

若要使文件出现在“文件”应用中,你必须在 Info.plist 中将以下键的值设置为 YES

  • UIFileSharingEnabled (Application supports iTunes file sharing)
  • LSSupportsOpeningDocumentsInPlace (Supports opening documents in place)

阅读 配置 iOS 以获取帮助。

Android

如果使用 Directory.DocumentsDirectory.ExternalStorage,在 Android 10 及更早版本中,此 API 要求将以下权限添加到你的 AndroidManifest.xml

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Android 指南 中阅读关于 设置权限 的部分,以获取有关设置 Android 权限的更多信息。

请注意,Directory.ExternalStorage 仅在 Android 9 或更早版本上可用,而 Directory.Documents 在 Android 11 及更新版本上仅允许访问你的应用创建的文件/文件夹。

处理大文件可能需要你在 AndroidManifest.xml<application> 标签中添加 android:largeHeap="true"

理解目录和文件

iOS 和 Android 在文件之间有额外的隔离层,例如备份到云端的特殊目录,或用于存储文档的目录。Filesystem API 提供了一种简单的方法,将每个操作限定在设备上的特定特殊目录内。

此外,Filesystem API 支持使用完整的 file:// 路径,或在 Android 上读取 content:// 文件。只需省略 directory 参数即可使用完整文件路径。

示例

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 () => {
// 这是一个读取完整文件路径文件的示例。使用此方法来
// 从返回 File URI 的插件(例如相机)读取二进制数据(base64 编码)。
const contents = await Filesystem.readFile({
path: "file:///var/mobile/Containers/Data/Application/22A433FD-D82D-4989-8BE6-9FC49DEA20BB/Documents/text.txt",
});

console.log("data:", contents);
};

const appendBinaryData = async () => {
// 这是一个追加二进制数据的示例,这些数据应以 base64 编码
// 的形式发送给插件,并且不指定任何 `Encoding`。
await Filesystem.appendFile({
path: "file.bin",
directory: Directory.Cache,
data: "VGhpcyBpcyBtZWFudCB0byByZXByZXNlbnQgYSBCaW5hcnkgRGF0YSBleGFtcGxlIGVuY29kZWQgaW4gQmFzZTY0Lg=="
});
};
```## API

<docgen-index>

* [`checkPermissions()`](#checkpermissions)
* [`requestPermissions()`](#requestpermissions)
* [`readFile(...)`](#readfile)
* [`readFileInChunks(...)`](#readfileinchunks)
* [`writeFile(...)`](#writefile)
* [`appendFile(...)`](#appendfile)
* [`deleteFile(...)`](#deletefile)
* [`mkdir(...)`](#mkdir)
* [`rmdir(...)`](#rmdir)
* [`readdir(...)`](#readdir)
* [`getUri(...)`](#geturi)
* [`stat(...)`](#stat)
* [`rename(...)`](#rename)
* [`copy(...)`](#copy)
* [`downloadFile(...)`](#downloadfile)
* [`addListener('progress', ...)`](#addlistenerprogress-)
* [`removeAllListeners()`](#removealllisteners)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)
* [Enums](#enums)

</docgen-index>

现有错误代码列表请参见 [错误](#errors)。

<docgen-api>
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->

### checkPermissions()

```typescript
checkPermissions() => Promise<PermissionStatus>

检查读写权限。 仅在 Android 上使用 Directory.DocumentsDirectory.ExternalStorage 时需要。

返回:

Promise<PermissionStatus>

自: 1.0.0


requestPermissions()

requestPermissions() => Promise<PermissionStatus>

请求读写权限。 仅在 Android 上使用 Directory.DocumentsDirectory.ExternalStorage 时需要。

返回:

Promise<PermissionStatus>

自: 1.0.0


readFile(...)

readFile(options: ReadFileOptions) => Promise<ReadFileResult>

从磁盘读取文件

参数类型
options
ReadFileOptions

返回:

Promise<ReadFileResult>

自: 1.0.0


readFileInChunks(...)

readFileInChunks(options: ReadFileInChunksOptions, callback: ReadFileInChunksCallback) => Promise<CallbackID>

分块从磁盘读取文件。 仅限原生平台(Web 不可用)。 使用回调函数接收每个读取的数据块。 如果返回空块,则表示文件已完全读取。

参数类型
options
ReadFileInChunksOptions
callback
ReadFileInChunksCallback

返回: Promise<string>

自: 7.1.0


writeFile(...)

writeFile(options: WriteFileOptions) => Promise<WriteFileResult>

将文件写入设备的指定位置

参数类型
options
WriteFileOptions

返回:

Promise<WriteFileResult>

自: 1.0.0


appendFile(...)

appendFile(options: AppendFileOptions) => Promise<void>

在设备的指定位置向文件追加内容

参数类型
options
AppendFileOptions

自: 1.0.0


deleteFile(...)

deleteFile(options: DeleteFileOptions) => Promise<void>

从磁盘删除文件

参数类型
options
DeleteFileOptions

自: 1.0.0


mkdir(...)

mkdir(options: MkdirOptions) => Promise<void>

创建目录。

参数类型
options
MkdirOptions

自: 1.0.0


rmdir(...)

rmdir(options: RmdirOptions) => Promise<void>

删除目录

参数类型
options
RmdirOptions

自: 1.0.0


readdir(...)

readdir(options: ReaddirOptions) => Promise<ReaddirResult>

返回目录中的文件列表(非递归)

参数类型
options
ReaddirOptions

返回:

Promise<ReaddirResult>

自: 1.0.0


getUri(...)

getUri(options: GetUriOptions) => Promise<GetUriResult>

根据路径和目录返回完整的文件 URI

参数类型
options
GetUriOptions

返回:

Promise<GetUriResult>

自: 1.0.0


stat(...)

stat(options: StatOptions) => Promise<StatResult>

返回文件的相关数据

参数类型
options
StatOptions

返回:

Promise<FileInfo>

自: 1.0.0


rename(...)

rename(options: RenameOptions) => Promise<void>

重命名文件或目录

参数类型
options
CopyOptions

自: 1.0.0

--------------------### copy(...)

copy(options: CopyOptions) => Promise<CopyResult>

复制文件或目录

参数类型
options
CopyOptions

返回值:

Promise<CopyResult>

自版本: 1.0.0


downloadFile(...)

downloadFile(options: DownloadFileOptions) => Promise<DownloadFileResult>

向服务器发起 HTTP 请求并将文件下载到指定位置。

此方法自版本 7.1.0 起已弃用。 我们建议使用 @capacitor/file-transfer 插件替代,并与本插件配合使用。

参数类型
options
DownloadFileOptions

返回值:

Promise<DownloadFileResult>

自版本: 5.1.0


addListener('progress', ...)

addListener(eventName: 'progress', listenerFunc: ProgressListener) => Promise<PluginListenerHandle>

添加文件下载进度事件监听器。

此方法自版本 7.1.0 起已弃用。 我们建议使用 @capacitor/file-transfer 插件替代,并与本插件配合使用。

参数类型
eventName'progress'
listenerFunc
ProgressListener

返回值:

Promise<PluginListenerHandle>

自版本: 5.1.0


removeAllListeners()

removeAllListeners() => Promise<void>

移除此插件的所有监听器。

此方法自版本 7.1.0 起已弃用。 我们建议使用 @capacitor/file-transfer 插件替代,并与本插件配合使用。

自版本: 5.2.0


接口

PermissionStatus

属性类型
publicStorage
PermissionState

ReadFileResult

属性类型描述自版本
datastring | Blob文件中所包含数据的表示形式。注意: Blob 仅在 Web 端可用。在原生端,数据以字符串形式返回。1.0.0

ReadFileOptions

属性类型描述默认值自版本
pathstring要读取的文件路径1.0.0
directory
Directory
读取文件的 Directory1.0.0
encoding
Encoding
读取文件时使用的编码。如果未提供,则数据以二进制形式读取并返回 base64 编码。传递 Encoding.UTF8 可将数据作为字符串读取1.0.0
offsetnumber开始读取文件的字节偏移量。仅限原生端(Web 端不可用)。可与 length 配合使用以部分读取文件。08.1.0
lengthnumber要读取的数据长度(字节)。任何非正值表示读取到文件末尾。仅限原生端(Web 端不可用)。可与 offset 配合使用以部分读取文件。-18.1.0

ReadFileInChunksOptions

属性类型描述自版本
chunkSizenumber分块大小(字节)。7.1.0

WriteFileResult

属性类型描述自版本
uristring文件被写入后的 URI1.0.0
属性类型说明默认值始于版本
pathstring要写入的文件路径1.0.0
datastring | Blob要写入的数据
注意:Blob 数据仅在 Web 端受支持。
1.0.0
directory
Directory
存储文件的 Directory 目录1.0.0
encoding
Encoding
写入文件时使用的编码。如果未提供,将写入二进制数据。为此,你必须提供 base64 编码的数据,以便插件在写入磁盘前进行解码。如果未提供编码却使用了非 base64 数据,将抛出错误。传递 Encoding.UTF8 可将数据作为字符串写入。1.0.0
recursiveboolean是否创建所有缺失的父级目录。false1.0.0

AppendFileOptions

属性类型说明始于版本
pathstring要追加内容的文件路径1.0.0
datastring要追加的数据1.0.0
directory
Directory
存储文件的 Directory 目录1.0.0
encoding
Encoding
追加内容到文件时使用的编码。如果未提供,将追加二进制数据。为此,你必须提供 base64 编码的数据,以便插件在写入磁盘前进行解码。如果未提供编码却使用了非 base64 数据,将抛出错误。传递 Encoding.UTF8 可将数据作为字符串追加。1.0.0

DeleteFileOptions

属性类型说明始于版本
pathstring要删除的文件路径1.0.0
directory
Directory
从中删除文件的 Directory 目录1.0.0

MkdirOptions

属性类型说明默认值始于版本
pathstring新目录的路径1.0.0
directory
Directory
创建新目录的 Directory 目录1.0.0
recursiveboolean是否同时创建所有缺失的父级目录。false1.0.0
属性类型描述默认值始于
pathstring要删除目录的路径1.0.0
directory
Directory
要从中删除目录的 Directory1.0.0
recursiveboolean是否递归删除目录内容false1.0.0

ReaddirResult(读取目录结果)

属性类型描述始于
filesFileInfo[]目录内文件和目录的列表1.0.0

FileInfo(文件信息)

属性类型描述始于
namestring文件或目录的名称7.1.0
type'file' | 'directory'文件的类型4.0.0
sizenumber文件大小(字节)4.0.0
ctimenumber创建时间(毫秒)。Android 7 及更早版本不可用7.1.0
mtimenumber最后修改时间(毫秒)7.1.0
uristring文件的 URI4.0.0

ReaddirOptions(读取目录选项)

属性类型描述始于
pathstring要读取的目录路径1.0.0
directory
Directory
要从中列出文件的 Directory1.0.0

GetUriResult(获取 URI 结果)

属性类型描述始于
uristring文件的 URI1.0.0

GetUriOptions(获取 URI 选项)

属性类型描述始于
pathstring要获取 URI 的文件路径1.0.0
directory
Directory
文件所在的 Directory1.0.0

StatOptions(状态选项)

属性类型描述始于
pathstring要获取数据的文件路径1.0.0
directory
Directory
文件所在的 Directory1.0.0

CopyOptions(复制选项)

属性类型描述始于
fromstring源文件或目录1.0.0
tostring目标文件或目录1.0.0
directory
Directory
包含源文件或目录的 Directory1.0.0
toDirectory
Directory
包含目标文件或目录的 Directory。如果未提供,则使用 'directory' 参数作为目标位置1.0.0

CopyResult(复制结果)

属性类型描述始于
uristring文件被复制到的 URI4.0.0

DownloadFileResult(下载文件结果)

属性类型描述始于
pathstring文件下载到的路径5.1.0
blobBlob已下载文件的 Blob 数据。此属性仅在 Web 端可用5.1.0
属性类型说明默认值起始版本
pathstring下载的文件应移动到的路径。5.1.0
directory
Directory
写入文件的目录。如果使用此选项,filePath 可以是相对路径而非绝对路径。默认为 DATA 目录。5.1.0
progressboolean一个可选的监听函数,用于接收下载进度事件。如果使用此选项,应在每个接收到的数据块上派发进度事件。在 Android/iOS 上,数据块会被节流至每 100ms 一次,以避免性能下降。5.1.0
recursiveboolean是否创建任何缺失的父目录。false5.2.0

PluginListenerHandle

属性类型
remove() => Promise<void>

ProgressStatus

属性类型说明起始版本
urlstring正在下载的文件的 URL。5.1.0
bytesnumber目前已经下载的字节数。5.1.0
contentLengthnumber此文件需要下载的总字节数。5.1.0

类型别名

PermissionState

'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'

ReadFileInChunksCallback

用于接收从文件读取的数据块的回调函数,如果出错则返回错误。

(chunkRead: ReadFileResult | null, err?: any): void

CallbackID

string

StatResult

FileInfo

RenameOptions

CopyOptions

ProgressListener

接收进度事件的监听函数。

(progress: ProgressStatus): void

枚举#### 目录

成员描述自版本
Documents'DOCUMENTS'文档目录。在 iOS 上,这是应用的文档目录。使用此目录存储用户生成的内容。在 Android 上,这是公共文档文件夹,因此其他应用可以访问。在 Android 10 上不可访问,除非应用在 AndroidManifest.xmlapplication 标签中添加 android:requestLegacyExternalStorage="true" 以启用旧版外部存储。在 Android 11 或更高版本中,应用只能访问其创建的文件/文件夹。1.0.0
Data'DATA'数据目录。在 iOS 上,将使用文档目录。在 Android 上,这是存放应用文件的目录。应用卸载时文件会被删除。1.0.0
Library'LIBRARY'库目录。在 iOS 上,将使用库目录。在 Android 上,这是存放应用文件的目录。应用卸载时文件会被删除。1.1.0
Cache'CACHE'缓存目录。在内存不足时可能会被删除,因此请使用此目录写入应用特定的文件,这些文件可以轻松重新创建。1.0.0
External'EXTERNAL'外部目录。在 iOS 上,将使用文档目录。在 Android 上,这是主共享/外部存储设备上应用可以放置其拥有的持久文件的目录。这些文件对应用是内部的,通常不作为媒体对用户可见。应用卸载时文件会被删除。1.0.0
ExternalStorage'EXTERNAL_STORAGE'外部存储目录。在 iOS 上,将使用文档目录。在 Android 上,这是主共享/外部存储目录。在 Android 10 上不可访问,除非应用在 AndroidManifest.xmlapplication 标签中添加 android:requestLegacyExternalStorage="true" 以启用旧版外部存储。在 Android 11 或更高版本中不可访问。1.0.0
ExternalCache'EXTERNAL_CACHE'外部缓存目录。在 iOS 上,将使用文档目录。在 Android 上,这是主共享/外部缓存。7.1.0
LibraryNoCloud'LIBRARY_NO_CLOUD'无云端备份的库目录。用于 iOS。在 Android 上,这是存放应用文件的目录。7.1.0
Temporary'TEMPORARY'iOS 的临时目录。在 Android 上,这是存放应用缓存的目录。7.1.0

编码

成员描述自版本
UTF8'utf8'八位 UCS 转换格式1.0.0
ASCII'ascii'七位 ASCII,又称 ISO646-US 或 Unicode 字符集的基本拉丁块。此编码仅在 Android 上受支持。1.0.0
UTF16'utf16'十六位 UCS 转换格式,字节顺序由可选的字节顺序标记标识。此编码仅在 Android 上受支持。1.0.0

### 错误处理

自 7.1.0 版本起,本插件会在原生 Android 和 iOS 平台上返回带有特定代码的错误信息。Web 平台不遵循此错误标准。

以下表格列出了所有插件错误:

错误代码支持平台错误信息
OS-PLUG-FILE-0004iOSCordova / Capacitor 桥接未初始化
OS-PLUG-FILE-0005Android, iOS方法输入参数无效
OS-PLUG-FILE-0006Android, iOS提供的路径无效
OS-PLUG-FILE-0007Android无法执行文件操作,用户拒绝了权限请求
OS-PLUG-FILE-0008Android, iOS操作失败,文件不存在
OS-PLUG-FILE-0009Android不支持对提供的输入执行此操作
OS-PLUG-FILE-0010Android, iOS目录已存在,无法覆盖
OS-PLUG-FILE-0011Android, iOS缺少父目录 – 可能因传递了 recursive=false 或父目录创建失败
OS-PLUG-FILE-0012Android, iOS无法删除包含子项的目录;收到 recursive=false 但目录非空
OS-PLUG-FILE-0013Android, iOS操作失败,发生错误