上传、下载和文件访问 API 模块,支持文件流读写以处理大文件,简化网络访问及异步数据交互流程
当前访问频次受限,请登录后继续访问
react-native-fetch-blob
本项目基于 react-native-fetch-blob 开发,并适配 React Native for OpenHarmony。 如果在使用过程中有任何问题,可以在 GitCode 提交 Issue,我们会及时跟进。
项目介绍
本库面向 React Native 应用提供网络请求、文件上传下载、文件系统、文件流、会话管理及文档预览等能力,并已适配 HarmonyOS(React Native for OpenHarmony)。
@hxa-rn/react-native-fetch-blob 提供以下能力:
- 发起 HTTP 请求并读取文本、JSON、Base64 或文件响应。
- 将响应保存到指定路径或临时缓存文件。
- 上传文本、文件及 multipart 表单。
- 创建、读取、写入、移动、复制和删除应用沙箱内的文件或目录。
- 以流方式读写文件。
- 按会话管理临时文件。
- 使用 HarmonyOS Preview Kit 预览本地文档。
- 在配置保存目标的后台下载或 multipart 后台上传中使用 Request Kit,并查询后台任务。
集成指南
安装
在 React Native 工程根目录执行:
npm install @hxa-rn/react-native-fetch-blob
Autolinking
本库已提供 RNOH Autolinking 配置。正常安装依赖后,由工程的 RNOH 构建流程完成原生包链接,无需手动注册 FetchBlobPackage。
导入
import RNFetchBlob from '@hxa-rn/react-native-fetch-blob';
使用说明
基础用法
const directory = `${RNFetchBlob.fs.dirs.DocumentDir}/rn-fetch-blob`;
const filePath = `${directory}/example.txt`;
await RNFetchBlob.fs.mkdir(directory);
await RNFetchBlob.fs.writeFile(filePath, 'Hello HarmonyOS', 'utf8');
const content = await RNFetchBlob.fs.readFile(filePath, 'utf8');
console.info(content);
下载文件
const targetPath = `${RNFetchBlob.fs.dirs.CacheDir}/image.jpg`;
const task = RNFetchBlob.config({ path: targetPath }).fetch(
'GET',
'https://example.com/image.jpg' // 需替换为真实地址
);
task.progress({ interval: 100, count: 10 }, (written, total) => {
console.info(`download: ${written}/${total}`);
});
const response = await task;
console.info(response.path());
上传 multipart 表单
以下示例中的上传文件需要在调用前创建并写入内容。
const uploadPath = `${RNFetchBlob.fs.dirs.DocumentDir}/rn-fetch-blob/example.txt`;
const response = await RNFetchBlob.fetch(
'POST',
'https://example.com/upload', // 需替换为真实地址
{
'Content-Type': 'multipart/form-data',
},
[
{
name: 'file',
filename: 'example.txt',
type: 'text/plain',
data: RNFetchBlob.wrap(uploadPath),
},
{
name: 'description',
data: 'HarmonyOS upload',
},
]
);
console.info(response.info().status);
流式写入和读取
const streamPath = `${RNFetchBlob.fs.dirs.DocumentDir}/rn-fetch-blob/stream.txt`;
const writeStream = await RNFetchBlob.fs.writeStream(
streamPath,
'utf8',
false
);
await writeStream.write('first chunk\n');
await writeStream.write('second chunk\n');
await writeStream.close();
const readStream = await RNFetchBlob.fs.readStream(
streamPath,
'utf8',
4096,
10
);
readStream.onData(chunk => console.info(chunk));
readStream.onError(error => console.error(error));
readStream.onEnd(() => console.info('read finished'));
readStream.open();
后台下载
const backgroundPath = `${RNFetchBlob.fs.dirs.CacheDir}/background.bin`;
const task = RNFetchBlob.config({
path: backgroundPath,
background: true,
}).fetch('GET', 'https://example.com/file.bin'); // 需替换为真实地址
console.info(task.taskId);
const response = await task;
console.info(response.path());
也可以使用 IOSBackgroundTask: true 启用同一后台传输模式。后台下载必须同时配置 path 或 fileCache,后台上传仅适用于 multipart 数组请求。
RNFetchBlob.listBackgroundTasks(knownTasks) 可查询后台任务。跨进程关联要求调用方持久化 taskId、agentTaskId 和 targetPath 等任务信息;当前不承诺普通后台配置在应用重启后自动恢复任务。最新跨进程恢复修复的验证边界见“约束与限制”。
预览本地文件
以下示例中的文件需要在调用前创建。
const previewPath = `${RNFetchBlob.fs.dirs.DocumentDir}/rn-fetch-blob/example.txt`;
await RNFetchBlob.harmony.previewDocument(previewPath);
在 HarmonyOS 上,previewDocument 和 openDocument 使用 Preview Kit 打开本地文件。
接口文档
以下接口均来自当前公开 JavaScript API、TurboModule 声明及适配实现。未在当前实现中得到验证的旧版接口不列为支持接口。
顶层接口
| 接口 | 参数 | 返回值 | 说明 |
|---|---|---|---|
RNFetchBlob.fetch(method, url, headers?, body?) |
method: string;url: string;headers?: object;body?: string | object[] |
增强的 Promise<FetchBlobResponse> |
发起普通请求、文件请求或 multipart 请求。 |
RNFetchBlob.config(options) |
options: object |
{ fetch: Function } |
配置保存路径、缓存、超时、增量响应或后台传输。 |
RNFetchBlob.wrap(path) |
path: string |
string |
将本地路径转换为 RNFetchBlob-file:// 文件引用。 |
RNFetchBlob.session(name) |
name: string |
RNFetchBlobSession |
获取指定名称的文件会话。 |
RNFetchBlob.listBackgroundTasks(knownTasks?) |
knownTasks?: object[] |
Promise<object[]> |
查询后台传输任务;已知任务可携带任务标识和目标路径。 |
fetch() 返回的增强 Promise 提供以下成员:
| 成员 | 说明 |
|---|---|
.progress(callback) / .progress({ interval, count }, callback) |
监听下载进度。 |
.uploadProgress(callback) / .uploadProgress({ interval, count }, callback) |
监听上传进度。 |
.message(callback) |
监听诊断消息事件。 |
.part(callback) |
监听增量响应数据块。 |
.stateChange(callback) |
监听请求状态。 |
.expire(callback) |
监听超时事件。 |
.cancel(callback?) |
取消当前任务。 |
.taskId |
当前任务标识。 |
所有请求事件均按 taskId 隔离。
网络配置
| 配置项 | 类型 | 说明 |
|---|---|---|
path |
string |
将响应保存到指定路径。 |
fileCache |
boolean |
将响应保存为缓存文件。 |
appendExt |
string |
设置缓存文件扩展名。 |
timeout |
number |
设置请求超时时间。 |
increment |
boolean |
启用增量响应事件。 |
background |
boolean |
值为 true 时允许满足后台条件的请求使用 Request Kit。 |
IOSBackgroundTask |
boolean |
与 background: true 对应,保留上游兼容命名。 |
后台下载只有在同时配置 path 或 fileCache 时使用 Request Kit;后台上传仅适用于 multipart 数组请求。
响应对象
| 接口 | 返回值 | 说明 |
|---|---|---|
response.info() |
RNFetchBlobResponseInfo |
获取状态码、响应头等响应信息。 |
response.blob() |
Promise<Blob> |
将响应转换为 Blob。 |
response.text() |
string | Promise |
读取文本响应。 |
response.json() |
any | Promise |
解析 JSON 响应。 |
response.base64() |
string | Promise |
读取 Base64 响应。 |
response.flush() |
Promise | void |
删除路径型缓存文件。 |
response.path() |
string | null |
获取响应文件路径。 |
response.session(name) |
RNFetchBlobSession | null |
将响应文件加入指定会话。 |
response.readStream(encoding) |
Promise<RNFetchBlobReadStream> | null |
为路径型响应创建读流。 |
response.readFile(encoding) |
Promise | null |
读取路径型响应文件。 |
当前不应使用 response.array();该接口的文本和 Base64 分支尚未完整实现。
文件与目录
| 接口 | 参数 | 返回值 | 说明 |
|---|---|---|---|
fs.mkdir(path) |
path: string |
Promise |
创建目录。 |
fs.exists(path) |
path: string |
Promise<boolean> |
判断路径是否存在。 |
fs.isDir(path) |
path: string |
Promise<boolean> |
判断路径是否为目录。 |
fs.ls(path) |
path: string |
Promise<string[]> |
列出目录成员。 |
fs.createFile(path, data, encoding) |
data: string | number[];encoding: 'utf8' | 'ascii' | 'base64' |
Promise |
创建文件。ASCII 数据使用 number[],UTF-8/Base64 数据使用字符串。 |
fs.readFile(path, encoding) |
path: string;encoding: string |
Promise<any> |
读取文件。 |
fs.writeFile(path, data, encoding?) |
data: string | number[] |
Promise |
写入并覆盖文件。 |
fs.appendFile(path, data, encoding?) |
data: string | number[] |
Promise |
追加文件内容。 |
fs.unlink(path) |
path: string |
Promise |
删除文件或链接路径。 |
fs.cp(src, dest) |
src: string;dest: string |
Promise<void> |
复制文件。 |
fs.mv(src, dest) |
src: string;dest: string |
Promise<void> |
移动或重命名文件。 |
fs.stat(path) |
path: string |
Promise<RNFetchBlobFile> |
获取路径信息。 |
fs.lstat(path) |
path: string |
Promise<RNFetchBlobFile[]> |
获取目录子项信息,包含 filename、path、type、size、lastModified。 |
fs.slice(src, dest, start, end) |
start: number;end: number |
Promise |
将源文件指定区间写入目标文件。 |
fs.df() |
无 | Promise<{ free: number, total: number }> |
查询存储空间。 |
fs.dirs 提供 DocumentDir、CacheDir、PictureDir、MusicDir、MovieDir、DownloadDir、DCIMDir、SDCardDir、SDCardApplicationDir、MainBundleDir 和 LibraryDir。
文件编码仅支持 utf8 / utf-8、ascii 和 base64。非法编码会返回 INVALID_ENCODING,并在创建、截断文件或创建活动流前终止操作。
文件流
| 接口 | 参数 | 返回值 | 说明 |
|---|---|---|---|
fs.writeStream(path, encoding, append?) |
encoding: 'utf8' | 'ascii' | 'base64';append?: boolean |
Promise<RNFetchBlobWriteStream> |
创建写流。 |
writeStream.write(data) |
data: string | number[] |
Promise<void> |
写入数据;ASCII 使用 number[]。 |
writeStream.close() |
无 | Promise<void> |
关闭写流。 |
fs.readStream(path, encoding, bufferSize?, tick?) |
encoding: 'utf8' | 'ascii' | 'base64';bufferSize?: number;tick?: number |
Promise<RNFetchBlobReadStream> |
创建读流。 |
readStream.onData(callback) |
callback: Function |
void |
注册数据块回调。 |
readStream.onError(callback) |
callback: Function |
void |
注册错误回调。 |
readStream.onEnd(callback) |
callback: Function |
void |
注册结束回调。 |
readStream.open() |
无 | void |
开始读取。 |
Session
| 接口 | 返回值 | 说明 |
|---|---|---|
session.add(path) |
RNFetchBlobSession |
向会话添加文件路径。 |
session.remove(path) |
RNFetchBlobSession |
从会话记录移除文件路径。 |
session.list() |
string[] |
获取会话中的文件路径。 |
session.dispose() |
Promise |
删除会话文件并清理会话记录。 |
Harmony 文档接口
| 接口 | HarmonyOS 行为 |
|---|---|
RNFetchBlob.harmony.previewDocument(path) |
使用 Preview Kit 预览本地文件。 |
RNFetchBlob.harmony.openDocument(path) |
使用 Want 拉起系统/外部应用打开文件。 |
错误码
当前实现使用以下稳定错误码:
| 错误码 | 含义 |
|---|---|
ENOENT |
文件或路径不存在。 |
EACCES |
无访问权限。 |
ENOSPC |
存储空间不足。 |
INVALID_ENCODING |
不支持的文件编码。 |
NETWORK_ERROR |
网络请求失败。 |
TIMEOUT |
请求超时。 |
CANCELLED |
请求被取消。 |
INVALID_PATH |
文件路径无效。 |
快速验证(运行 Example)
前置条件
| 依赖 | 版本要求 |
|---|---|
| Node.js | >= 18 |
| React Native for OpenHarmony | 0.72.139 |
| HarmonyOS SDK | 6.0.1(21)+ |
运行步骤
- 在仓库根目录安装依赖并打包生成 tgz:
npm install
npm pack
- 进入
example目录并安装依赖:
cd example
npm install
- 生成 HarmonyOS Bundle:
npm run dev
- 使用 DevEco Studio 打开
example/harmony工程,构建并运行到目标设备。
约束与限制
兼容性
| 依赖 | 要求 |
|---|---|
| React Native for OpenHarmony | 0.72.139 |
| HarmonyOS SDK | 6.0.1(21)+ |
Example 工程 compatibleSdkVersion |
6.0.1(21) |
Example 工程 targetSdkVersion |
6.1.1(24) |
| Node.js | >= 18 |
本库 peerDependencies 要求 React Native >= 0.72;当前示例工程已通过 TypeScript、Codegen、HAR、静态门禁和 HAP 构建检查。
使用限制
response.array()的文本和 Base64 分支尚未完整实现,请使用text()、base64()或文件读取接口。fs.asset()仍保留上游公开入口并会生成bundle-assets://字符串,但当前 HarmonyOS 网络与文件读取路径没有经过验证的该 URI 消费链路,因此本文不将其列为已支持资源读取接口。RNFetchBlob不再导出ios与android对象。- Request Kit 后台任务的行为受系统调度、网络状态和应用生命周期影响。
- 最新跨进程后台任务恢复修复已通过构建和静态检查,但尚未完成该修复版本的重新安装、强杀进程和真机复测。因此本文不宣称全部接口已通过最新版本全量真机验证。
系统权限
- 网络请求、上传、下载和后台传输依赖
ohos.permission.INTERNET。 - 当前 HAR 未声明其他系统权限。
开源 License
本项目采用 MIT,与上游项目保持一致。
问题反馈渠道
如在使用过程中遇到问题,请在 GitCode 提交 Issue,我们会及时跟进。
- 提交问题时建议附上项目版本、RN 版本、OpenHarmony SDK/API 版本、DevEco Studio 版本、设备信息、复现步骤及相关日志。
- 涉及签名、账号、密钥或用户数据时,请勿在 Issue 中上传敏感信息;可按组织安全流程提交脱敏日志。