@react-native-ohos/react-native-blob-util
v0.19.9
Published
A module provides upload, download, and files access API. Supports file stream read/write for process large files.
Downloads
1,106
Readme
文档模板:v0.4.2
本项目基于 [email protected]开发。
该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-blob-util,具体版本所属关系如下:
| 三方库名称 | 三方库版本 | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | npm地址 | | ------------ | ------------ | ------------------------------ |---------------| ------------- |------------------------ |---------------| ------------- | | @react-native-ohos/react-native-blob-util | ~ 0.19.8 | Gitcode Releases | 0.72.* | 是 | API12+ | 0.19.6 | Npm Address | | @react-native-oh-tpl/react-native-blob-util| <= 0.19.7@deprecated | Github Releases(deprecated) | 0.72.* | 否 | API12+ | 0.19.6 | Npm Address |
简介
react-native-blob-util 是跨平台 RN 二进制网络文件与本地文件操作原生库,支持大文件上传下载、流式读写,解决 fetch 处理二进制文件 OOM 问题。
下载安装
进入到工程目录并输入以下命令:
npm
npm install @react-native-ohos/react-native-blob-utilyarn
yarn add @react-native-ohos/react-native-blob-utilLink
| | 是否支持autolink | RN框架版本 | | -------------------- | ---------------- | ---------- | | ~ 0.19.8 | Yes | 0.72.* | | <= 0.19.7@deprecated | No | 0.72.* |
使用AutoLink的工程需要根据该文档配置,Autolink框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md
如您使用的版本支持 Autolink,并且工程已接入 Autolink,可跳过ManualLink配置。
1. Overrides RN SDK
为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 oh-package.json5 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。
关于该字段的作用请阅读官方说明
{
"overrides": {
"@rnoh/react-native-openharmony": "^0.72.38" // ohpm 在线版本
// "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // 指向本地 har 包的路径
// "@rnoh/react-native-openharmony" : "./react_native_openharmony" // 指向源码路径
}
}2. 引入原生端代码
目前有两种方法:
- 通过 har 包引入;
- 直接链接源码。
方法一:通过 har 包引入(推荐)
[!TIP] har 包位于三方库安装路径的
harmony文件夹下。
打开 entry/oh-package.json5,添加以下依赖
"dependencies": {
"@react-native-ohos/react-native-blob-util": "file:../../node_modules/@react-native-ohos/react-native-blob-util/harmony/blobUtil.har"
}点击右上角的 sync 按钮
或者在命令行终端执行:
cd entry
ohpm install方法二:直接链接源码
[!TIP] 如需使用直接链接源码,请参考直接链接源码说明
3. 配置 CMakeLists 和引入 BlobUtilPackage
打开 entry/src/main/cpp/CMakeLists.txt,添加:
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-blob-util/src/main/cpp" ./blob-util)
# RNOH_END: manual_package_linking_1
file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")
add_library(rnoh_app SHARED
${GENERATED_CPP_FILES}
"./PackageProvider.cpp"
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)
# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_blob_util)
# RNOH_END: manual_package_linking_2打开 entry/src/main/cpp/PackageProvider.cpp,添加:
#include "RNOH/PackageProvider.h"
#include "SamplePackage.h"
+ #include "BlobUtilPackage.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<SamplePackage>(ctx),
+ std::make_shared<RNBlobUtilPackage>(ctx),
};
}4. 在 ArkTs 侧引入 BlobUtilPackage
打开 entry/src/main/ets/RNPackagesFactory.ts,添加:
+ import {BlobUtilPackage} from '@react-native-ohos/react-native-blob-util/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
+ new BlobUtilPackage(ctx)
];
}运行
点击右上角的 sync 按钮
或者在终端执行:
cd entry
ohpm install然后编译、运行即可。
约束与限制
兼容性
本文档内容基于以下版本验证通过:
- RNOH: 0.72.98; SDK: HarmonyOS-5.0.0(API12); IDE: DevEco Studio 5.0.3.906; ROM: NEXT.0.0.71;
权限要求
上传下载需要申请网络权限
在
entry/src/main/module.json5中添加
requestPermissions: [
{
name: "ohos.permission.INTERNET",
},
],使用示例
下面的代码展示了这个库的基本使用场景:
[!WARNING] 使用时 import 的库名不变。
import React, { useState } from "react";
import {
ScrollView,
StyleSheet,
Button,
View,
Text,
NativeEventEmitter,
} from "react-native";
import ReactNativeBlobUtil from "react-native-blob-util";
export default function BlobUtilDemo() {
const [result, setResult] = useState<string | null>(null);
const [mkdirParam, setMkdirParam] = useState("");
const createFile = async () => {
await ReactNativeBlobUtil.fs.createFile(
result + "/text.txt",
"123456",
"utf8"
);
};
const ls = async () => {
await ReactNativeBlobUtil.fs.ls(ReactNativeBlobUtil.fs.dirs.CacheDir);
};
const unlink = () => {
ReactNativeBlobUtil.fs.unlink(result + "/text.txt");
};
const getConstants = () => {
let obj = ReactNativeBlobUtil.fs.dirs.CacheDir;
setResult(obj);
};
const writeFile = () => {
ReactNativeBlobUtil.fs.writeFile(
result + "/text.txt",
"Try to write str",
"utf8"
);
};
const writeStream = () => {
ReactNativeBlobUtil.fs.writeStream(result + "/text.txt", "utf8", false);
};
const writeArrayChunk = () => {
ReactNativeBlobUtil.fs
.writeStream(result + "/text.txt", "ascii", false)
.then((reactNativeBlobUtilWriteStream:any) => {
reactNativeBlobUtilWriteStream.write([101, 32, 97]);
reactNativeBlobUtilWriteStream.close();
});
};
const writeChunk = () => {
ReactNativeBlobUtil.fs
.writeStream(result + "/text.txt", "utf8", false)
.then((reactNativeBlobUtilWriteStream:any) => {
reactNativeBlobUtilWriteStream.write("Zm9vIChXcml0ZSBCYXNlNjQpMQ==");
reactNativeBlobUtilWriteStream.close();
});
};
const closeStream = () => {
ReactNativeBlobUtil.fs
.writeStream(result + "/text.txt", "utf8", false)
.then((reactNativeBlobUtilWriteStream:any) => {
setTimeout(() => {
reactNativeBlobUtilWriteStream.close();
}, 1000);
});
};
const readStream = () => {
ReactNativeBlobUtil.fs.readStream(result + "/text.txt", "utf8", 4000, 200);
};
const mkdir = () => {
ReactNativeBlobUtil.fs.mkdir(
ReactNativeBlobUtil.fs.dirs.DocumentDir + "/" + mkdirParam
);
};
const stat = () => {
ReactNativeBlobUtil.fs.stat(result + "/text.txt");
};
const copyFileToCache = () => {
ReactNativeBlobUtil.fs.cp(result + "/text.txt", result + "/text1.txt");
};
const writeFileArray = () => {
ReactNativeBlobUtil.fs.writeFile(
result + "/text.txt",
[102, 111, 111],
"ascii"
);
};
const exists = () => {
ReactNativeBlobUtil.fs.exists(result + "/text.txt");
};
const lstat = () => {
ReactNativeBlobUtil.fs.lstat(result + "/text.txt");
};
const mv = () => {
ReactNativeBlobUtil.fs.mv(result + "/text.txt", result + "/text1.txt");
};
const hash = () => {
ReactNativeBlobUtil.fs.hash(result + "/text.txt", "md5");
};
const readFile = () => {
ReactNativeBlobUtil.fs.readFile(result + "/text.txt", "utf8", 4000);
};
const slice = () => {
ReactNativeBlobUtil.fs.slice(
result + "/text.txt",
result + "/text1.txt",
2,
5
);
};
const df = () => {
ReactNativeBlobUtil.fs.df();
};
const addListener = () => {
let obj = "addListener是空实现";
setResult(obj);
};
const removeListeners = () => {
let obj = "removeListeners是空实现";
setResult(obj);
};
const emitExpiredEvent = () => {
let obj = "emitExpiredEvent是空实现,三方库没有调用";
setResult(obj);
};
return (
<View style={styles.container}>
<View style={styles.titleArea}>
<Text style={styles.title}>BlobUtil</Text>
</View>
<View style={styles.inputArea}>
<Text style={styles.baseText} ellipsizeMode="tail" numberOfLines={2}>{result}</Text>
</View>
<ScrollView style={styles.scrollView}>
<View style={{ flexDirection: "column" }}>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.getConstants()</Text>
<Button
title="运行"
color="#841584"
onPress={getConstants}
></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.createFile()</Text>
<Button title="运行" color="#841584" onPress={createFile}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.unlink()</Text>
<Button title="运行" color="#841584" onPress={unlink}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>
BlobUtilTurboModule.copyFileToCache()
</Text>
<Button
title="运行"
color="#841584"
onPress={copyFileToCache}
></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.writeFile()</Text>
<Button title="运行" color="#841584" onPress={writeFile}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.stat()</Text>
<Button title="运行" color="#841584" onPress={stat}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.mkdir()</Text>
<Button title="运行" color="#841584" onPress={mkdir}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.writeStream()</Text>
<Button title="运行" color="#841584" onPress={writeStream}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.ls()</Text>
<Button title="运行" color="#841584" onPress={ls}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>
BlobUtilTurboModule.writeFileArray()
</Text>
<Button
title="运行"
color="#841584"
onPress={writeFileArray}
></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.exists()</Text>
<Button title="运行" color="#841584" onPress={exists}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.lstat()</Text>
<Button title="运行" color="#841584" onPress={lstat}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.hash()</Text>
<Button title="运行" color="#841584" onPress={hash}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.readFile()</Text>
<Button title="运行" color="#841584" onPress={readFile}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.slice()</Text>
<Button title="运行" color="#841584" onPress={slice}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.df()</Text>
<Button title="运行" color="#841584" onPress={df}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.closeStream()</Text>
<Button title="运行" color="#841584" onPress={closeStream}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>
BlobUtilTurboModule.writeArrayChunk()
</Text>
<Button
title="运行"
color="#841584"
onPress={writeArrayChunk}
></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.writeChunk()</Text>
<Button title="运行" color="#841584" onPress={writeChunk}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.readStream()</Text>
<Button title="运行" color="#841584" onPress={readStream}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>BlobUtilTurboModule.mv()</Text>
<Button title="运行" color="#841584" onPress={mv}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>addListener()</Text>
<Button title="运行" color="#841584" onPress={addListener}></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>removeListeners()</Text>
<Button
title="运行"
color="#841584"
onPress={removeListeners}
></Button>
</View>
<View style={styles.baseArea}>
<Text style={{ flex: 1 }}>emitExpiredEvent()</Text>
<Button
title="运行"
color="#841584"
onPress={emitExpiredEvent}
></Button>
</View>
</View>
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
width: "100%",
height: "100%",
flexDirection: "column",
alignItems: "center",
backgroundColor: "#F1F3F5",
},
baseText: {
width: "100%",
height: "100%",
fontWeight: "bold",
textAlign: "center",
fontSize: 16,
},
titleArea: {
width: "90%",
height: "8%",
alignItems: "center",
flexDirection: "row",
},
title: {
width: "90%",
color: "#000000",
textAlign: "left",
fontSize: 30,
},
scrollView: {
width: "90%",
marginHorizontal: 10,
},
inputArea: {
width: "90%",
height: "10%",
borderWidth: 2,
borderColor: "#000000",
marginTop: 8,
justifyContent: "center",
alignItems: "center",
},
baseArea: {
width: "100%",
height: 60,
borderRadius: 4,
borderColor: "#000000",
marginTop: 6,
backgroundColor: "#FFFFFF",
flexDirection: "row",
alignItems: "center",
paddingLeft: 8,
paddingRight: 8,
},
});使用说明
下载
ReactNativeBlobUtil.config({
fileCache: true,
timeout: 20000,
indicator: true,
})
.fetch(
"GET",
"https://xxx.xx.demo.zip",
).then((res) => {
console.log(res.data, "aaa");
if (res.data) {
setState(true)
setText(res.data)
}
}).catch((err) => {
console.log(err, "err");
})上传
const filePath = ReactNativeBlobUtil.fs.dirs.CacheDir + '/fetch.txt';
ReactNativeBlobUtil.config({
timeout: 20000,
indicator: true,
})
.fetch(
"POST",
"https://xxx.xx.demo.zip",
{
'Content-Type': 'multipart/form-data',
},
[{
name: 'file',
filename: 'fetch.txt',
// upload a file from asset is also possible in version >= 0.6.2
data: ReactNativeBlobUtil.wrap(filePath)
}]
)
.then((res) => {
if (res.data) {
setState(true)
}
})文件操作
// 获取缓存目录下的文件与文件夹列表
ReactNativeBlobUtil.fs.ls(ReactNativeBlobUtil.fs.dirs.CacheDir);
// 删除指定文件 text.txt
ReactNativeBlobUtil.fs.unlink(result + "/text.txt");
// 以utf8编码向路径写入字符串
ReactNativeBlobUtil.fs.writeFile(
result + "/text.txt",
"Try to write str",
"utf8"
);
// 创建文件写入流,utf8编码,false = 不追加(覆盖模式),仅初始化流,未写入数据
ReactNativeBlobUtil.fs.writeStream(result + "/text.txt", "utf8", false);
// 创建ascii编码写入流
ReactNativeBlobUtil.fs
.writeStream(result + "/text.txt", "ascii", false)
.then((reactNativeBlobUtilWriteStream:any) => {
reactNativeBlobUtilWriteStream.write([101, 32, 97]);
reactNativeBlobUtilWriteStream.close();
});
// 创建utf8覆盖写入流
ReactNativeBlobUtil.fs
.writeStream(result + "/text.txt", "utf8", false)
.then((reactNativeBlobUtilWriteStream:any) => {
setTimeout(() => {
reactNativeBlobUtilWriteStream.close();
}, 1000);
});
// 创建文件读取流,utf8编码,分片最大4000字节,起始偏移200
ReactNativeBlobUtil.fs.readStream(result + "/text.txt", "utf8", 4000, 200);
// 在Document目录下创建新文件夹
ReactNativeBlobUtil.fs.mkdir(
ReactNativeBlobUtil.fs.dirs.DocumentDir + "/" + mkdirParam
);
// 获取文件stat信息(跟随软链接,读取目标文件元数据)
ReactNativeBlobUtil.fs.stat(result + "/text.txt");
// 复制文件
ReactNativeBlobUtil.fs.cp(result + "/text.txt", result + "/text1.txt");
// ascii编码写入字节数组
ReactNativeBlobUtil.fs.writeFile(result + "/text.txt", [102, 111, 111], "ascii");
// 判断文件/目录是否存在
ReactNativeBlobUtil.fs.exists(result + "/text.txt");
// 获取lstat信息(不跟随软链接,读取链接自身元数据)
ReactNativeBlobUtil.fs.lstat(result + "/text.txt");
// 移动文件(重命名)
ReactNativeBlobUtil.fs.mv(result + "/text.txt", result + "/text1.txt");
// 对文件计算md5哈希值
ReactNativeBlobUtil.fs.hash(result + "/text.txt", "md5");
// utf8读取文件内容
ReactNativeBlobUtil.fs.readFile(result + "/text.txt", "utf8", 4000);
// 文件切片
ReactNativeBlobUtil.fs.slice(result + "/text.txt", result + "/text1.txt", 2, 5);接口说明
[!TIP] "Platform"列表示该属性在原三方库上支持的平台。
[!TIP] "OpenHarmony Support"列为 yes 表示 OpenHarmony平台支持 该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
组件
| 名称 | 参数类型 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ------------------- | ------------------------- | ---- | ---- | ------------------- | ------------------------- | | ReactNativeBlobUtil | ReactNativeBlobUtilStatic | yes | all | yes | ReactNativeBlobUtil组件。 |
属性
Dirs
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | --------------------- | -------- | ------ | ---- | ------------ | ------------------- | ------------------------------------------------------------ | | DocumentDir | string | "" | No | iOS, Android | Yes | 应用文档/文件目录,映射到 context.filesDir。 | | CacheDir | string | "" | No | iOS, Android | Yes | 应用缓存目录,映射到 context.cacheDir。 | | PictureDir | string | "" | No | iOS, Android | Yes | 图片目录,映射到 context.filesDir + '/picture' | | LibraryDir | string | "" | No | iOS | No | iOS Library 目录。 | | MusicDir | string | "" | No | iOS, Android | Yes | 音乐目录,映射到 context.filesDir + '/music'。 | | MovieDir | string | "" | No | iOS, Android | Yes | 视频目录,映射到 context.filesDir + '/movie'。 | | DownloadDir | string | "" | No | iOS, Android | Yes | 下载目录,映射到 context.filesDir(同 DocumentDir)。 | | DCIMDir | string | "" | No | Android | No | Android DCIM(相机照片)目录。 | | SDCardDir | string | "" | No | Android | No | Android SD 卡根目录(已废弃)。 | | SDCardApplicationDir | string | "" | No | Android | No | Android 应用专属 SD 卡目录(已废弃)。 | | MainBundleDir | string | "" | No | iOS | Yes | iOS Main Bundle 目录,映射到 context.bundleCodeDir(Hap 资源包目录)。 | | ApplicationSupportDir | string | "" | No | iOS | No | iOS Application Support 目录 | | LegacyPictureDir | string | "" | No | Android | No | Android 旧版图片目录。 | | LegacyMusicDir | string | "" | No | Android | No | Android 旧版音乐目录。 | | LegacyMovieDir | string | "" | No | Android | No | Android 旧版视频目录。 | | LegacyDownloadDir | string | "" | No | Android | No | Android 旧版下载目录。 | | LegacyDCIMDir | string | "" | No | Android | No | Android 旧版 DCIM 目录。 | | LegacySDCardDir | string | "" | No | Android | No | Android 旧版 SD 卡目录(已废弃)。 |
ReactNativeBlobUtilConfig
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ------------------- | ------------------------------------- | --------- | ---- | ------------ | ------------------- | ------------------------------------- | | Progress | { count?: number; interval?: number } | undefined | No | iOS, Android | No | 下载进度报告配置。 | | UploadProgress | { count?: number; interval?: number } | undefined | No | iOS, Android | No | 上传进度报告配置。 | | overwrite | boolean | true | No | iOS, Android | No | 是否覆盖已存在文件。 | | timeout | number | 60000 | No | iOS, Android | Yes | 请求超时时间(毫秒)。 | | indicator | boolean | false | No | iOS | No | 在 iOS 状态栏显示网络活动指示器。 | | trusty | boolean | false | No | iOS, Android | No | 允许自签名SSL证书。 | | wifiOnly | boolean | false | No | iOS, Android | No | 仅通过 WiFi 发起请求。 | | followRedirect | boolean | true | No | iOS, Android | No | 是否跟随 HTTP 重定向。 | | fileCache | boolean | false | No | iOS, Android | No | 将响应缓存为临时文件。 | | transformFile | boolean | false | No | iOS, Android | No | 保存前通过 FileTransformer 处理数据。 | | appendExt | string | "" | No | iOS, Android | Yes | 临时文件扩展名。 | | path | string | "" | No | iOS, Android | Yes | 指定下载文件存储路径。 | | session | string | "" | No | iOS, Android | No | 文件跟踪会话名称。 | | addAndroidDownloads | AddAndroidDownloads | undefined | No | Android | No | Android Download Manager 集成配置。 | | IOSBackgroundTask | boolean | false | No | iOS | No | 启用 iOS 后台 URL Session 模式。 |
AddAndroidDownloads
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ------------------ | -------- | ------------ | ---- | ------- | ------------------- | ------------------------------------------------ | | useDownloadManager | boolean | false | No | Android | No | 使用 Android 系统 DownloadManager。 | | title | string | "" | No | Android | No | 下载通知标题。 | | description | string | "" | No | Android | No | 下载描述。 | | path | string | "" | No | Android | No | 下载目标路径(须为外部存储)。 | | mime | string | "text/plain" | No | Android | No | MIME 类型(默认 text/plain)。 | | mediaScannable | boolean | false | No | Android | No | 使文件可被 MediaScanner 扫描。 | | storeInDownloads | boolean | false | No | Android | No | 存储到 MediaCollection Downloads(Android Q+)。 | | notification | boolean | false | No | Android | No | 显示下载通知。 | | storeLocal | boolean | false | No | Android | No | 保存到应用 Download 目录。 |
API
ReactNativeBlobUtilStatic
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---------------------------------- | ---- | ------------ | ------------------- | ------------------------------------------------------------ | | fetch | function | (method: Methods, url: string, headers?: { [key: string]: string }, body?: any|null) | StatefulPromise | No | iOS, Android | Yes | 发起 HTTP(S) 请求(GET/POST/PUT/DELETE/PATCH),返回 StatefulPromise,支持进度/取消。 | | base64 | { encode(input: string): string; decode(input: string): string }; | / | / | No | iOS, Android | Yes | Base64 编解码工具对象(encode/decode)。 | | android | AndroidApi | / | / | No | iOS, Android | No | Android api 对象。 | | ios | IOSApi | / | / | No | iOS, Android | Partially | iOS api 对象。 | | config | function | (options: ReactNativeBlobUtilConfig) | ReactNativeBlobUtilStatic | No | iOS, Android | Partially | 注入请求配置项,返回带配置的 fetch 方法。 | | session | function | (name: string) | ReactNativeBlobUtilSession | No | iOS, Android | Yes | 获取/创建文件缓存会话。 | | fs | FS | / | / | No | iOS, Android | Partially | 文件系统操作命名空间。 | | MediaCollection | MediaCollection | / | / | No | Android | No | Android MediaStore 集成。 | | wrap | function | (path: string) | string | No | iOS, Android | Yes | 将路径包装为 ReactNativeBlobUtil-file:// 前缀的。 | | net | Net | / | / | No | iOS, Android | No | 网络工具:getCookies/removeCookies。 | | polyfill | Polyfill | / | / | No | iOS, Android | No | Web API Polyfill(Blob/File/XHR/Fetch 等)。 | | JSONStream | function | (arg: string|Object) | any | No | iOS, Android | No | 流式 JSON 解析器(基于 Oboe.js)。 | | CanceledFetchError | type | any | / | No | iOS, Android | Yes | fetch 取消时抛出的自定义错误类。 |
FS
ReactNativeBlobUtil.fs
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ---------------------- | -------- | ------------------------------------------------------------ | ----------------- | ---- | ------------ | ------------------- | -------------------------------------------------------- | | unlink | function | (path: string) | Promise | No | iOS, Android | Yes | 删除指定路径的文件。 | | mkdir | function | (path: string) | Promise | No | iOS, Android | Yes | 创建目录(递归创建)。 | | session | function | (name: string) | any | No | iOS, Android | Yes | 获取/创建文件缓存会话。 | | ls | function | (path: string) | Promise<string[]> | No | iOS, Android | Yes | 列出目录内容,返回文件名数组。 | | hash | function | (path: string, algorithm: HashAlgorithm) | Promise | No | iOS, Android | Yes | 计算文件哈希。 | | readStream | function | (path: string, encoding: Encoding, bufferSize?: number, tick?: number) | Promise | No | iOS, Android | Yes | 创建可读文件流,按块分发数据。 | | mv | function | (path: string, dest: string) | Promise | No | iOS, Android | Yes | 移动/重命名文件。 | | cp | function | (path: string, dest: string) | Promise | No | iOS, Android | Yes | 复制文件。 | | writeStream | function | (path: string, encoding: Encoding, append?: boolean) | Promise | No | iOS, Android | Yes | 创建可写文件流。 | | writeFile | function | (path: string, data: string|number[], encoding?: Encoding) | Promise | No | iOS, Android | Yes | 写入数据到文件(utf8/base64/ascii)。 | | writeFileWithTransform | function | (path: string, data: string|number[], encoding?: Encoding) | Promise | No | iOS, Android | No | 通过 FileTransformer 写入文件。 | | appendFile | function | (path: string, data: string|number[], encoding?: Encoding|"uri") | Promise | No | iOS, Android | Yes | 追加数据到文件。 | | readFile | function | (path: string, encoding: Encoding, bufferSize?: number) | Promise | No | iOS, Android | Yes | 读取整个文件内容。 | | readFileWithTransform | function | (path: string, encoding: Encoding, bufferSize?: number) | Promise | No | iOS, Android | No | 通过 FileTransformer 读取文件。 | | exists | function | (path: string) | Promise | No | iOS, Android | Yes | 检查文件/目录是否存在。 | | createFile | function | (path: string, data: string|number[], encoding: Encoding) | Promise | No | iOS, Android | Yes | 创建新文件并写入内容。 | | isDir | function | (path: string) | Promise | No | iOS, Android | Yes | 检查路径是否为目录。 | | stat | function | (path: string) | Promise | No | iOS, Android | Yes | 获取文件/目录元数据(size/lastModified/type/filename)。 | | lstat | function | (path: string) | Promise<any[]> | No | iOS, Android | Yes | 列出目录条目及其元数据。 | | scanFile | function | (pairs: Array<{ [key: string]: string }>) | Promise | No | Android | No | 请求 Android MediaScanner 扫描文件。 | | dirs | Dirs | / | / | Yes | iOS, Android | Yes | 获取文件系统各地址。 | | slice | function | (src: string, dest: string, start: number, end: number) | Promise | No | iOS, Android | Yes | 从文件中提取指定字节范围到新文件。 | | asset | function | (path: string) | string | No | iOS | Yes | 将路径转换为 bundle-assets:// uri。 | | df | function | / | Promise | No | iOS, Android | Yes | 获取文件系统可用/总空间。 | | pathForAppGroup | function | (groupName: string) | Promise | No | iOS | No | 获取 iOS App Group 共享容器路径。 | | syncPathAppGroup | function | (groupName: string) | string | No | iOS | No | 同步获取 iOS App Group 共享容器路径 |
StatefulPromise
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | -------------- | -------- | ------------------------------------------------------------ | ---------------------------------- | ---- | ------------ | ------------------- | --------------------------------------- | | cancel | function | (cb?: (reason: any) => void) | StatefulPromise | No | iOS, Android | Yes | 取消 HTTP 请求。 | | progress | function | (config: { count?: number; interval?: number }, callback: (received: number, total: number) => void) | StatefulPromise | No | iOS, Android | Yes | 注册下载进度回调。 | | uploadProgress | function | (config: { count?: number; interval?: number }, callback: (sent: number, total: number) => void) | StatefulPromise | No | iOS, Android | Yes | 注册上传进度回调。 | | expire | function | (callback: () => void) | StatefulPromise | No | iOS | No | iOS 后台任务到期回调(约180秒后触发)。 |
FetchBlobResponse
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ---------- | ------------------------ | ---------------------------------------- | --------------------- | ---- | ------------ | ------------------- | -------------------------------------- | | taskId | string | / | / | No | iOS, Android | Yes | 任务 ID 字符串。 | | path | function | / | string | No | iOS, Android | Yes | 返回缓存临时文件路径。 | | type | "base64"|"path"|"utf8" | / | / | No | iOS, Android | Yes | 响应数据类型:"base64"/"path"/"utf8"。 | | data | any | / | / | No | iOS, Android | Yes | 原始响应数据。 | | blob | function | (contentType: string, sliceSize: number) | Promise | No | iOS, Android | Yes | 转换为 PolyfillBlob 对象。 | | text | function | / | string|Promise | No | iOS, Android | Yes | 解码为文本字符串。 | | json | function | / | any | No | iOS, Android | Yes | 解析为 JSON 对象。 | | base64 | function | / | any | No | iOS, Android | Yes | 获取 BASE64 编码字符串。 | | flush | function | / | / | No | iOS, Android | Yes | 删除响应缓存文件。 | | respInfo | object | / | / | No | iOS, Android | Yes | 响应元数据。 | | info | function | / | any | No | iOS, Android | Yes | 获取响应信息。 | | session | function | (name: string) | any|null | No | iOS, Android | Yes | 将响应文件添加到会话。 | | readFile | function | (encode: Encoding) | Promise|null | No | iOS, Android | Yes | 按指定编码读取缓存响应文件。 | | readStream | function | (encode: Encoding) | any|null | No | iOS, Android | Yes | 在缓存响应文件上创建读取流。 |
Net
ReactNativeBlobUtil.net
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ------------- | -------- | ----------------- | ----------------- | ---- | ------------ | ------------------- | ---------------------------- | | getCookies | function | (domain: string) | Promise<string[]> | No | iOS, Android | No | 获取指定域名的 Cookie 列表。 | | removeCookies | function | (domain?: string) | Promise | No | iOS, Android | No | 删除指定域名的 Cookie。 |
IOSApi
ReactNativeBlobUtil.ios
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | -------------------- | -------- | ------------------------------- | ------------- | ---- | ---- | ------------------- | -------------------------------------- | | previewDocument | function | (path: string, scheme?: string) | / | No | iOS | Yes | 预览文档。 | | openDocument | function | (path: string, scheme?: string) | Promise | No | iOS | Yes | previewDocument 的旧版别名。 | | presentOptionsMenu | function | (path: string, scheme?: string) | / | No | iOS | No | 显示文档交互选项菜单。 | | presentOpenInMenu | function | (path: string, scheme?: string) | / | No | iOS | No | 显示"打开方式"菜单。 | | presentPreview | function | (path: string, scheme?: string) | / | No | iOS | No | 全屏预览。 | | excludeFromBackupKey | function | (path: string) | Promise | No | iOS | No | 标记文件/目录排除 iCloud/iTunes 备份。 |
AndroidApi
ReactNativeBlobUtil.android
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ----------------------- | -------- | --------------------------------------------------- | ---------------------- | ---- | ------- | ------------------- | -------------------------------------------- | | actionViewIntent | function | (path: string, mime: string, chooserTitle?: string) | Promise<boolean|null> | No | Android | No | 发送 ACTION_VIEW Intent 用系统应用打开文件。 | | getContentIntent | function | (mime: string) | Promise | No | Android | No | 启动系统文件选择器,选择后返回文件 URI。 | | addCompleteDownload | function | (options: AndroidDownloadOption) | Promise | No | Android | No | 添加已完成下载条目到系统下载应用。 | | getSDCardDir | function | / | Promise | No | Android | No | 获取 SD 卡根目录路径。 | | getSDCardApplicationDir | function | / | Promise | No | Android | No | 获取应用专属 SD 卡目录路径。 |
MediaCollection
ReactNativeBlobUtil.MediaCollection
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ----------------------------- | -------- | ------------------------------------------------------------ | --------------- | ---- | ------- | ------------------- | ----------------------------------------- | | copyToMediaStore | function | (filedata: filedescriptor, mediatype: Mediatype, path: string) | Promise | No | Android | No | 复制文件到 Android MediaStore。 | | createMediafile | function | (filedata: filedescriptor, mediatype: Mediatype) | Promise | No | Android | No | 在 MediaStore 中创建新文件条目。 | | writeToMediafile | function | (uri: string, path: string) | Promise | No | Android | No | 向 MediaStore 文件写入数据。 | | writeToMediafileWithTransform | function | (uri: string, path: string) | Promise | No | Android | No | 通过 FileTransformer 向 MediaStore 写入。 | | copyToInternal | function | (contenturi: string, destpath: string) | Promise | No | Android | No | 从 MediaStore 复制文件到应用内部存储。 | | getBlob | function | (contenturi: string, encoding: string) | Promise | No | Android | No | 读取 MediaStore 文件数据为 Blob。 |
ReactNativeBlobUtilSession
ReactNativeBlobUtil.session
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | OpenHarmony平台支持 | 描述 | | ------- | -------- | -------------- | -------------------------- | ---- | ------------ | ------------------- | ------------------------------------ | | add | function | (path: string) | ReactNativeBlobUtilSession | No | iOS, Android | Yes | 向此会话添加文件路径。 | | remove | function | (path: string) | ReactNativeBlobUtilSession | No | iOS, Android | Yes | 从此会话中删除会话条目而不删除文件。 | | dispose | function | / | Promise | No | iOS, Android | Yes | 删除会话中的所有文件。 | | list | function | / | string[] | No | iOS, Android | Yes | 返回包含此会话中的文件路径的数组。 |
遗留问题
- [ ] blob-util在使用getCookies、removeCookies 在Android、iOS、Harmony OS 上使用都会报错: issue#381
其他
无
目录结构
/rntpc_react-native-blob-util # 项目根目录
├── harmony # 鸿蒙平台适配代码
│ └── blobUtil.har # 编译产出HAR静态包
│ └── blobUtil # 鸿蒙适配核心源码目录
│ └── Index.ets # 鸿蒙适配代码统一入口
│ └── ts.ets # ArkTS 类型导出入口文件
│ └── src/main
│ └── ets # ArkTS 业务实现层
│ └── BlobUtilTurboModule.ts # 鸿蒙侧 TurboModule 实现
│ └── BlobUtilPackage.ets # 鸿蒙侧 Package
│ └── Logger.ets # 日志工具
│ └── ReactNativeBlobUtil # 核心功能实现分组目录
│ └── ReactNativeBlobUtilImpl.ts # 顶层统一调度实现
│ └── ReactNativeBlobUtilFS.ts # 文件系统相关接口实现
│ └── ReactNativeBlobUtilReq.ts # 基础网络请求实现
│ └── ReactNativeBlobUtilStream.ts# 文件流读写逻辑实现
│ └── ReactNativeBlobUtilConfig.ts # 请求配置管理模块
│ └── turboModules # TurboModule 接口定义目录
│ └── generated # Codegen自动生成桥接代码(禁止手动修改)
│ └── down # 文件下载业务模块
│ └── upload # 文件上传业务模块
│ └── utils # 通用工具类目录
│ └── components # ArkUI页面组件目录
│ └── cpp # C++胶水层代码(RNOH桥接层)
│ └── BlobUtilPackage.h # C++层Package头文件
│ └── CMakeLists.txt # C++编译构建配置
│ └── generated # Codegen自动生成桥接代码(禁止手动修改)
├── example # Demo演示工程目录
├── README.md # 中文使用文档
└── README_en.md # 英文使用文档贡献代码
使用过程中发现任何问题都可以提交 Issue,当然,也非常欢迎提交 PR 。
开源协议
本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。
