Skip to content

Commit 7dbb538

Browse files
author
baofeng
committed
新增existsAssets,readDir,downloadFile接口
1 parent 15b6056 commit 7dbb538

File tree

7 files changed

+208
-26
lines changed

7 files changed

+208
-26
lines changed

FS.common.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ var RNFS = {
271271
},
272272

273273
// Android-only
274-
existsAssets(filepath: string) {
274+
existsAssets(filepath: string):Promise<boolean> {
275275
if (!RNFSManager.existsAssets) {
276276
throw new Error('existsAssets is not available on this platform');
277277
}

harmony/fs.har

-5.47 KB
Binary file not shown.

harmony/fs/oh-package.json5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@react-native-oh-tpl/react-native-fs",
3-
"version": "2.20.0-0.1.3",
3+
"version": "2.20.0-0.1.4",
44
"description": "Please describe the basic information.",
55
"main": "index.ets",
66
"types": "module",

harmony/fs/src/main/ets/FsTurboModule.ts

Lines changed: 184 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,19 @@
2222
* SOFTWARE.
2323
*/
2424

25-
import { TurboModule, RNOHError } from '@rnoh/react-native-openharmony/ts';
26-
import fs, { ReadTextOptions, WriteOptions } from '@ohos.file.fs';
25+
import { TurboModule, RNOHError, TurboModuleContext } from '@rnoh/react-native-openharmony/ts';
26+
import { TM } from "@rnoh/react-native-openharmony/generated/ts"
27+
import fs, { ListFileOptions, ReadOptions, ReadTextOptions, WriteOptions } from '@ohos.file.fs';
2728
import hash from '@ohos.file.hash';
2829
import { BusinessError } from '@ohos.base';
29-
import common from '@ohos.app.ability.common';
30+
import resourceManager from '@ohos.resourceManager'
3031
import util from '@ohos.util';
32+
import loadRequest from '@ohos.request';
3133
import buffer from '@ohos.buffer';
3234
import HashMap from '@ohos.util.HashMap';
3335
import Logger from './Logger';
36+
import { Context } from '@ohos.abilityAccessCtrl';
37+
import common from '@ohos.app.ability.common';
3438

3539
const TAG: string = "[RNOH] Fs"
3640

@@ -43,11 +47,177 @@ interface StatResult {
4347
type: number // Is the file just a file? Is the file a directory?
4448
}
4549

46-
export class FsTurboModule extends TurboModule {
50+
type Headers = { [name: string]: string }
51+
type Fields = { [name: string]: string }
52+
53+
type DownloadFileOptions = {
54+
jobId: number
55+
fromUrl: string // URL to download file from
56+
toFile: string // Local filesystem path to save the file to
57+
headers?: Headers // An object of headers to be passed to the server
58+
background?: boolean // Continue the download in the background after the app terminates (iOS only)
59+
progressInterval?: number
60+
progressDivider?: number
61+
readTimeout?: number
62+
hasBeginCallback?: (res: DownloadBeginCallbackResult) => void
63+
hasProgressCallback?: (res: DownloadProgressCallbackResult) => void
64+
hasResumableCallback?: () => void // only supported on iOS yet
65+
connectionTimeout?: number // only supported on Android yet
66+
backgroundTimeout?: number // Maximum time (in milliseconds) to download an entire resource (iOS only, useful for timing out background downloads)
67+
}
68+
69+
type DownloadBeginCallbackResult = {
70+
jobId: number // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
71+
statusCode: number // The HTTP status code
72+
contentLength: number // The total size in bytes of the download resource
73+
headers: Headers // The HTTP response headers from the server
74+
}
75+
76+
type DownloadProgressCallbackResult = {
77+
jobId: number // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
78+
contentLength: number // The total size in bytes of the download resource
79+
bytesWritten: number // The number of bytes written to the file so far
80+
}
81+
82+
type DownloadResult = {
83+
jobId: number // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
84+
statusCode: number // The HTTP status code
85+
bytesWritten: number // The number of bytes written to the file
86+
}
87+
88+
type ReadDirItem = {
89+
ctime?: number;
90+
mtime?: number;
91+
name: string;
92+
path: string;
93+
size: number;
94+
type: number;
95+
};
96+
97+
export class FsTurboModule extends TurboModule implements TM.ReactNativeFs.Spec {
98+
private context: Context; // ApplicationContext
99+
private resourceManager: resourceManager.ResourceManager;
100+
101+
constructor(ctx: TurboModuleContext) {
102+
super(ctx)
103+
this.context = this.ctx.uiAbilityContext;
104+
this.resourceManager = this.context.resourceManager;
105+
}
106+
107+
existsAssets(filepath: string): Promise<boolean> {
108+
return new Promise((resolve, reject) => {
109+
try {
110+
this.resourceManager.getRawFileList(filepath, (error: BusinessError, value: Array<string>) => {
111+
if (error != null) {
112+
resolve(false);
113+
} else {
114+
resolve(true);
115+
}
116+
});
117+
} catch (error) {
118+
resolve(false);
119+
}
120+
});
121+
}
122+
123+
readDir(dirpath: string): Promise<Object[]> {
124+
return new Promise((resolve, reject) => {
125+
let listFileOption: ListFileOptions = {
126+
recursion: false,
127+
listNum: 0
128+
};
129+
fs.listFile(dirpath, listFileOption, (err: BusinessError, filenames: Array<string>) => {
130+
if (err) {
131+
reject("list file failed with error message: " + err.message + ", error code: " + err.code);
132+
} else {
133+
let readDirResult: ReadDirItem[] = [];
134+
for (let i = 0; i < filenames.length; i++) {
135+
let filename = filenames[i];
136+
let filePath = dirpath + filename;
137+
let file = fs.statSync(filePath);
138+
readDirResult.push({
139+
ctime: file.ctime,
140+
mtime: file.mtime,
141+
name: filename,
142+
path: filePath,
143+
size: file.size,
144+
type: file.isDirectory() ? 1 : 0,
145+
});
146+
}
147+
resolve(readDirResult);
148+
}
149+
});
150+
});
151+
}
152+
153+
downloadFile(options: Object): Promise<DownloadResult> {
154+
return new Promise((resolve, reject) => {
155+
let downloadFileOptions: DownloadFileOptions = options as DownloadFileOptions;
156+
let downloadConfig: loadRequest.DownloadConfig = {
157+
url: downloadFileOptions.fromUrl,
158+
header: downloadFileOptions.headers,
159+
enableMetered: true,
160+
enableRoaming: true,
161+
description: "",
162+
filePath: downloadFileOptions.toFile,
163+
title: '',
164+
background: true
165+
};
166+
167+
loadRequest.downloadFile((this.context as common.BaseContext), downloadConfig)
168+
.then((downloadTask: loadRequest.DownloadTask) => {
169+
if (downloadTask) {
170+
let loadTask: loadRequest.DownloadTask | null = downloadTask;
171+
172+
if (downloadFileOptions.hasBeginCallback) {
173+
let downloadBeginCallbackResult: DownloadBeginCallbackResult = {
174+
jobId: downloadFileOptions.jobId,
175+
statusCode: 0,
176+
contentLength: 0,
177+
headers: downloadFileOptions.headers
178+
}
179+
this.ctx.rnInstance.emitDeviceEvent('DownloadBegin', downloadBeginCallbackResult)
180+
}
181+
if (downloadFileOptions.hasProgressCallback) {
182+
loadTask.on('progress', (receivedSize, totalSize) => {
183+
if (totalSize > 0) {
184+
let downloadProgressCallbackResult: DownloadProgressCallbackResult = {
185+
jobId: downloadFileOptions.jobId,
186+
contentLength: totalSize,
187+
bytesWritten: receivedSize
188+
}
189+
this.ctx.rnInstance.emitDeviceEvent('DownloadProgress', downloadProgressCallbackResult)
190+
}
191+
});
192+
}
193+
194+
loadTask.on('complete', () => {
195+
let downloadResult: DownloadResult = {
196+
jobId: downloadFileOptions.jobId,
197+
statusCode: 200,
198+
bytesWritten: 0
199+
}
200+
resolve(downloadResult);
201+
})
202+
loadTask.on('pause', () => {
203+
})
204+
205+
loadTask.on('remove', () => {
206+
})
207+
loadTask.on('fail', (err) => {
208+
reject(JSON.stringify(err));
209+
})
210+
} else {
211+
reject("downloadTask dismiss");
212+
}
213+
}).catch((err: BusinessError) => {
214+
reject(JSON.stringify(err));
215+
})
216+
});
217+
}
47218

48-
context = getContext(this) as common.ApplicationContext; // ApplicationContext
49219
// 常量
50-
getConstants(): object {
220+
getConstants(): Object {
51221
return {
52222
// 沙箱路径
53223
FileSandBoxPath: this.context.filesDir,
@@ -63,14 +233,18 @@ export class FsTurboModule extends TurboModule {
63233
// 读取文件内容
64234
readFile(path: string): Promise<string> {
65235
return new Promise((resolve, reject) => {
66-
fs.readText(path, (err: BusinessError, content: string) => {
236+
let file = fs.openSync(path, fs.OpenMode.READ_WRITE);
237+
let arrayBuffer = new ArrayBuffer(4096);
238+
fs.read(file.fd, arrayBuffer, (err: BusinessError, readLen: number) => {
67239
if (err) {
68-
reject('Failed to read the file');
240+
reject("read failed with error message: " + err.message + ", error code: " + err.code);
69241
} else {
70-
let result = buffer.from(content, 'utf8').toString('base64');
242+
let result = buffer.from(arrayBuffer, 0, readLen).toString('base64');
71243
resolve(result);
72244
}
245+
fs.closeSync(file);
73246
});
247+
74248
})
75249
};
76250

@@ -145,8 +319,7 @@ export class FsTurboModule extends TurboModule {
145319
// 资源文件内容读取
146320
readFileAssets(path: string): Promise<string> {
147321
return new Promise((resolve, reject) => {
148-
this.context.resourceManager.getRawFileContent(
149-
path, (err: BusinessError, value) => {
322+
this.resourceManager.getRawFileContent(path, (err: BusinessError, value: Uint8Array) => {
150323
if (err) {
151324
reject(err.message);
152325
} else {

harmony/fs/ts.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,3 @@
2323
*/
2424

2525
export * from "./src/main/ets/FsPackage"
26-
export * from "./src/main/ets/FsTurboModule"

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@react-native-oh-tpl/react-native-fs",
3-
"version": "2.20.0-0.1.3",
3+
"version": "2.20.0-0.1.4",
44
"description": "Native filesystem access for react-native",
55
"main": "FS.common.js",
66
"typings": "index.d.ts",
@@ -9,7 +9,12 @@
99
"flow": "flow; test $? -eq 0 -o $? -eq 2"
1010
},
1111
"harmony": {
12-
"alias": "react-native-fs"
12+
"alias": "react-native-fs",
13+
"codegenConfig": {
14+
"specPaths": [
15+
"./src"
16+
]
17+
}
1318
},
1419
"repository": {
1520
"type": "git",

src/NativeReactNativeFs..js renamed to src/NativeReactNativeFs..ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,15 @@ type StatResult = {
1616
type: number // Is the file just a file? // Is the file a directory?
1717
};
1818

19+
type DownloadResult = {
20+
jobId: number; // The download job ID, required if one wishes to cancel the download. See `stopDownload`.
21+
statusCode: number; // The HTTP status code
22+
bytesWritten: number; // The number of bytes written to the file
23+
};
24+
1925
export interface Spec extends TurboModule {
20-
getConstants: () => {
21-
// System paths. 沙箱路径
22-
FileSandBoxPath: string;
23-
// 缓存路径
24-
FileCachePath: string;
25-
// 文件
26-
RNFSFileTypeRegular:number;
27-
// 文件夹
28-
RNFSFileTypeDirectory:number;
29-
};
26+
getConstants(): Object;
27+
3028
readFile(path: string): Promise<string>;
3129

3230
exists(path: string): Promise<boolean>;
@@ -54,6 +52,13 @@ export interface Spec extends TurboModule {
5452
stat(filepath: string): Promise<StatResult>;
5553

5654
touch(filepath: string, mtime?: number, ctime?: number): Promise<boolean>;
55+
56+
downloadFile(bridgeOptions: Object): Promise<DownloadResult>;
57+
58+
readDir(dirpath: string): Promise<Object[]>;
59+
60+
existsAssets(filepath: string):Promise<boolean>;
61+
5762
}
5863

5964
export default TurboModuleRegistry.getEnforcing<Spec>('ReactNativeFs');

0 commit comments

Comments
 (0)