@hxa-rn/rn-fetch-blob
v0.12.0-beta.1
Published
A module provides upload, download, and files access API. Supports file stream read/write for process large files.
Downloads
124
Readme
本项目基于 rn-fetch-blob开发。如果在使用过程中有任何问题,欢迎在AtomGit提交Issue,会及时跟进。
项目介绍
@hxa-rn/rn-fetch-blob 是 rn-fetch-blob 的 React Native 鸿蒙(OpenHarmony)适配包,提供上传、下载与文件系统访问能力,支持文件流读写以处理大文件。当前版本 0.12.0-beta.1。
| 鸿蒙适配包版本 | 原始库版本 | 支持 RN 版本 | Autolink | 编译 API 版本 | | ------------ | ---------- | ------------ | -------- | ------------- | | 0.12.0-beta.1 | 0.12.0 | 0.72+ | 是 | API12+ |
集成指南
npm install @hxa-rn/rn-fetch-blobpeerDependencies:react-native >= 0.72。
import 时使用原库名 'rn-fetch-blob',而非鸿蒙适配包名 '@hxa-rn/rn-fetch-blob'(harmony.alias 已配置为 rn-fetch-blob)。
当前版本支持 Autolink;若工程已接入 Autolink,可跳过手动配置。
本模块需要同时在 C++ 侧和 ETS 侧注册 Package。
1. Overrides RN SDK
在工程根目录 oh-package.json5 添加:
{
"overrides": {
"@rnoh/react-native-openharmony": "./react_native_openharmony"
}
}2. 引入原生端依赖
打开 entry/oh-package.json5,添加:
"dependencies": {
"@hxa-rn/rn-fetch-blob": "file:../../node_modules/@hxa-rn/rn-fetch-blob/harmony/fetch_blob.har"
}执行 ohpm install。
3. 配置 CMakeLists
打开 entry/src/main/cpp/CMakeLists.txt,添加:
set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
add_subdirectory("${OH_MODULES}/@hxa-rn/rn-fetch-blob/src/main/cpp" ./fetch_blob)
target_link_libraries(rnoh_app PUBLIC fetch_blob)4. 注册 Package(C++ 侧)
打开 entry/src/main/cpp/PackageProvider.cpp,添加:
#include "FetchBlobPackage.h"
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<FetchBlobPackage>(ctx),
};
}5. 注册 Package(ETS 侧)
打开 entry/src/main/ets/RNPackagesFactory.ets,添加:
import { FetchBlobPackage } from '@hxa-rn/rn-fetch-blob';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
new FetchBlobPackage(ctx),
];
}使用说明
import RNFetchBlob from 'rn-fetch-blob';
async function run() {
// 1. HTTP 文件下载
const resp = await RNFetchBlob.config({
fileCache: true,
appendExt: 'png',
path: `${RNFetchBlob.fs.dirs.DocumentDir}/sample.png`,
timeout: 30000,
}).fetch('GET', 'https://picsum.photos/200/300');
const filePath = resp.path();
const info = resp.respInfo;
console.log('saved to:', filePath, 'status:', info.status);
// 2. 下载进度
await RNFetchBlob.config({ fileCache: true })
.fetch('GET', 'https://picsum.photos/200/300')
.progress({ count: 1, interval: 100 }, (received, total) => {
console.log(`received ${received} / ${total}`);
});
// 3. POST JSON
await RNFetchBlob.config({})
.fetch(
'POST',
'https://httpbin.org/post',
{ 'Content-Type': 'application/json' },
JSON.stringify({ name: 'test' }),
);
// 4. 文件系统
await RNFetchBlob.fs.createFile(
`${RNFetchBlob.fs.dirs.DocumentDir}/a.txt`,
'Hello',
'utf8',
);
const content = await RNFetchBlob.fs.readFile(
`${RNFetchBlob.fs.dirs.DocumentDir}/a.txt`,
'utf8',
);
console.log('file content:', content);
await RNFetchBlob.fs.unlink(`${RNFetchBlob.fs.dirs.DocumentDir}/a.txt`);
}
run();平台差异:
- 目录常量:
DocumentDir/CacheDir/PictureDir/MusicDir/MovieDir/DownloadDir映射鸿蒙应用沙箱绝对路径;DCIMDir/SDCardDir/SDCardApplicationDir/LibraryDir鸿蒙无对应外部存储概念,降级返回''或应用沙箱路径 - 不支持 API:
fs.scanFile、android.addCompleteDownload、ios.previewDocument/openDocument/excludeFromBackupKey、fs.pathForAppGroup—— 调用时 reject / callback 返回… is not supported on HarmonyOS,业务需 try-catch(详解见下方「遗留问题」) syncPathAppGroup返回'';emitExpiredEvent为空实现(不列入「不支持」报告,见下方约束)actionViewIntent使用@kit.PreviewKit预览文件;getContentIntent使用@ohos.file.pickerDocumentViewPickerwifiOnly/trusty/followRedirect等配置项已按鸿蒙@ohos.net.http语义实现
接口文档
| API | 描述 | 参数 | 返回值 | HarmonyOS 支持 |
|-----|------|------|--------|----------------|
| config(options) | 注入请求配置(fileCache/path/timeout/appendExt 等) | RNFetchBlobConfig | RNFetchBlobStatic | ✅ |
| fetch(method, url, headers?, body?) | 发起 HTTP 请求,支持 GET/POST/PUT/DELETE 与 multipart | method, url, headers, body | StatefulPromise<FetchBlobResponse> | ✅ |
| .progress(config?, cb) | 下载进度上报 | {count,interval}, (received,total)=>void | 链式 Promise | ✅ |
| .uploadProgress(config?, cb) | 上传进度上报 | {count,interval}, (sent,total)=>void | 链式 Promise | ✅ |
| .cancel(cb?) | 取消进行中的请求 | 可选回调 | 链式 Promise | ✅ |
| .stateChange(cb) | HTTP 状态变化事件(state 2 = header 就绪) | (state)=>void | 链式 Promise | ✅ |
| session(name) | 获取/创建缓存会话 | name | RNFetchBlobSession | ✅ |
| fs.dirs | 应用目录常量集合 | - | Dirs | ✅ |
| fs.createFile(path, data, encoding) | 创建文本/二进制文件 | path, data, encoding | Promise<string> | ✅ |
| fs.createFileASCII(path, dataArray) | 创建 ASCII 文件 | path, number[] | Promise<void> | ✅ |
| fs.readFile(path, encoding) | 读取文件(utf8/base64/ascii) | path, encoding | Promise<string \| number[]> | ✅ |
| fs.writeFile(path, data, encoding) | 写入文件 | path, data, encoding | Promise<void> | ✅ |
| fs.appendFile(path, data, encoding) | 追加内容 | path, data, encoding | Promise<number> | ✅ |
| fs.unlink(path) | 删除文件 | path | Promise<void> | ✅ |
| fs.mkdir(path) | 创建目录 | path | Promise<void> | ✅ |
| fs.exists(path) | 判断路径是否存在 | path | Promise<boolean> | ✅ |
| fs.isDir(path) | 判断是否为目录 | path | Promise<boolean> | ✅ |
| fs.ls(path) | 列出目录内容 | path | Promise<string[]> | ✅ |
| fs.stat(path) | 获取文件状态 | path | Promise<RNFetchBlobStat> | ✅ |
| fs.lstat(path) | 获取符号链接状态 | path | Promise<RNFetchBlobStat[]> | ✅ |
| fs.cp(src, dest) | 复制文件 | src, dest | Promise<boolean> | ✅ |
| fs.mv(src, dest) | 移动文件 | src, dest | Promise<boolean> | ✅ |
| fs.slice(src, dest, start, end) | 文件切片 | src, dest, start, end | Promise<void> | ✅ |
| fs.hash(path, algorithm) | 计算文件哈希 | path, md5/sha1/sha256 | Promise<string> | ✅ |
| fs.df() | 查询磁盘空间 | - | Promise<{free,total}> | ✅ |
| fs.writeStream(path, encoding, append) | 开启写入流 | path, encoding, append | Promise<WriteStream> | ✅ |
| fs.writeChunk(streamId, data) | 写入流数据块 | streamId, data | Promise<void> | ✅ |
| fs.writeArrayChunk(streamId, dataArray) | 写入字节数组块 | streamId, number[] | Promise<void> | ✅ |
| fs.closeStream(streamId) | 关闭写入流 | streamId | Promise<void> | ✅ |
| fs.readStream(path, encoding, bufferSize, tick) | 开启读取流(data/end/error 事件) | path, encoding, bufferSize, tick | Promise<ReadStream> | ✅ |
| fs.removeSession(paths) | 批量删除会话缓存文件 | string[] | Promise<void> | ✅ |
| fs.asset(path) | 映射应用资源路径 | path | string | ✅ |
| android.actionViewIntent(path, mime) | 系统文件预览 | path, mime | Promise<void> | ✅ |
| android.getContentIntent(mime) | 内容选择器选文件 | mime | Promise<string> | ✅ |
| android.addCompleteDownload(config) | 添加下载记录 | config | Promise<void> | ❌ 否(U-02) |
| android.getSDCardDir() | 获取 SD 卡目录 | - | Promise<string> | ⚠️ 沙箱路径 |
| android.getSDCardApplicationDir() | 获取 SD 卡应用目录 | - | Promise<string> | ⚠️ 沙箱路径 |
| fs.scanFile(pairs) | 媒体文件扫描入相册 | Array<{path}> | Promise<void> | ❌ 否(U-01) |
| ios.previewDocument(uri, scheme) | iOS 文档预览 | uri, scheme | Promise<void> | ❌ 否(U-03) |
| ios.openDocument(uri, scheme) | iOS 文档打开 | uri, scheme | Promise<void> | ❌ 否(U-04) |
| ios.excludeFromBackupKey(url) | iOS 排除备份 | url | Promise<void> | ❌ 否(U-05) |
| fs.pathForAppGroup(group) | iOS App Group 路径 | group | Promise<string> | ❌ 否(U-06) |
| fs.syncPathAppGroup(group) | iOS App Group 同步 | group | string | ⚠️ 返回 '' |
✅ = 鸿蒙原生实现;⚠️ = 降级/沙箱替代实现(不列入不支持报告);❌ = 鸿蒙不支持,返回
… is not supported on HarmonyOS(编号见下方「遗留问题」)。 目录常量获取方式:RNFetchBlob.fs.dirs.DocumentDir等(getConstants()映射)。
快速验证(运行 Example)
前置条件
| 依赖 | 版本要求 | |------|----------| | Node.js | >= 18 | | DevEco Studio | 5.0+ | | HarmonyOS SDK | API 12+ |
运行步骤
1. 克隆仓库
git clone https://gitcode.com/hxa-rn/rn-fetch-blob.git
cd rn-fetch-blob
git checkout br_rnoh0.722. 安装仓库开发依赖
npm install --legacy-peer-depsExample 已改为从 npm 公仓安装 @hxa-rn/[email protected],不再使用本地 file:../xxx.tgz,运行 Example 不必再执行 npm pack。
3. 进入 example 目录,安装依赖
cd example # 或 example_auto
npm install --legacy-peer-deps4. 生成 JS Bundle
npm run dev产物:harmony/entry/src/main/resources/rawfile/bundle.harmony.js
5. 用 DevEco Studio 打开鸿蒙工程
- 打开 DevEco Studio
- 选择
example/harmony(或example_auto/harmony)目录 - 等待 Sync 完成
6. 编译并运行 HAP
在 DevEco Studio 中点击运行按钮,将 HAP 安装到设备/模拟器。
注意:Example 中已预置插件依赖和 Package 注册,无需手动配置 Link。Example 已声明
ohos.permission.INTERNET(HTTP 请求必需)。
约束与限制
兼容性
- 鸿蒙 SDK:API 12+
- 上游 RN 库:rn-fetch-blob 0.12.0
- React Native / RNOH:0.72+
- DevEco Studio:5.0+
权限
ohos.permission.INTERNET(HTTP 请求必需,需在entry/src/main/module.json5的requestPermissions中声明)
平台能力差异
- 大文件(GB 级)响应体按
path/fileCache落盘,避免读入内存导致 OOM wifiOnly仅对蜂窝数据网络生效(与 Android SDK21+ 语义一致)trusty信任自签名证书场景受鸿蒙系统 CA 策略限制getSDCardDir/getSDCardApplicationDir无外部 SD 概念,返回应用filesDirsyncPathAppGroup返回空串;emitExpiredEvent为空实现(iOS AppState 过期网络事件,鸿蒙无对等触发)
开源license
本项目基于 MIT 协议,详见 LICENSE 文件。
问题反馈渠道
使用问题请在 AtomGit 提交 Issue。也可在 GitCode 仓库反馈:
https://gitcode.com/hxa-rn/rn-fetch-blob
https://gitcode.com/hxa-rn/rn-fetch-blob/issues
