Skip to content

Commit b7de0ba

Browse files
committed
update fs
1 parent dcd66cb commit b7de0ba

File tree

5 files changed

+231
-7
lines changed

5 files changed

+231
-7
lines changed

FS.common.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ var utf8 = require('utf8');
1919
var isIOS = require('react-native').Platform.OS === 'ios';
2020
var isWindows = require('react-native').Platform.OS === 'windows'; // To accommodate Windows
2121

22-
var RNFSFileTypeRegular = RNFSManager.RNFSFileTypeRegular;
23-
var RNFSFileTypeDirectory = RNFSManager.RNFSFileTypeDirectory;
22+
var RNFSFileTypeRegular = (isIOS || isWindows )? RNFSManager.RNFSFileTypeRegular:RNFSManager.getConstants().RNFSFileTypeRegular;
23+
var RNFSFileTypeDirectory = (isIOS || isWindows )?RNFSManager.RNFSFileTypeDirectory:RNFSManager.getConstants().RNFSFileTypeDirectory;
2424

2525
var jobId = 0;
2626

harmony/fs.har

1.18 KB
Binary file not shown.

harmony/fs/src/main/cpp/FsTurboModule.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,41 @@ static jsi::Value __hostFunction_FsTurboModule_readFileAssets(jsi::Runtime &rt,
7979
return static_cast<ArkTSTurboModule &>(turboModule).callAsync(rt, "readFileAssets", args, count);
8080
}
8181

82-
static jsi::Value __hostFunction_NativeFsSpecJSI_unlink(jsi::Runtime &rt, react::TurboModule &turboModule,
82+
static jsi::Value __hostFunction_FsTurboModule_unlink(jsi::Runtime &rt, react::TurboModule &turboModule,
8383
const jsi::Value *args, size_t count) {
8484
return static_cast<ArkTSTurboModule &>(turboModule).callAsync(rt, "unlink", args, count);
8585
}
8686

87+
static jsi::Value __hostFunction_FsTurboModule_hash(jsi::Runtime &rt, react::TurboModule &turboModule,
88+
const jsi::Value *args, size_t count) {
89+
return static_cast<ArkTSTurboModule &>(turboModule).callAsync(rt, "hash", args, count);
90+
}
91+
92+
static jsi::Value __hostFunction_FsTurboModule_moveFile(jsi::Runtime &rt, react::TurboModule &turboModule,
93+
const jsi::Value *args, size_t count) {
94+
return static_cast<ArkTSTurboModule &>(turboModule).callAsync(rt, "moveFile", args, count);
95+
}
96+
97+
static jsi::Value __hostFunction_FsTurboModule_read(jsi::Runtime &rt, react::TurboModule &turboModule,
98+
const jsi::Value *args, size_t count) {
99+
return static_cast<ArkTSTurboModule &>(turboModule).callAsync(rt, "read", args, count);
100+
}
101+
102+
static jsi::Value __hostFunction_FsTurboModule_write(jsi::Runtime &rt, react::TurboModule &turboModule,
103+
const jsi::Value *args, size_t count) {
104+
return static_cast<ArkTSTurboModule &>(turboModule).callAsync(rt, "write", args, count);
105+
}
106+
107+
static jsi::Value __hostFunction_FsTurboModule_touch(jsi::Runtime &rt, react::TurboModule &turboModule,
108+
const jsi::Value *args, size_t count) {
109+
return static_cast<ArkTSTurboModule &>(turboModule).callAsync(rt, "touch", args, count);
110+
}
111+
112+
static jsi::Value __hostFunction_FsTurboModule_stat(jsi::Runtime &rt, react::TurboModule &turboModule,
113+
const jsi::Value *args, size_t count) {
114+
return static_cast<ArkTSTurboModule &>(turboModule).callAsync(rt, "stat", args, count);
115+
}
116+
87117
FsTurboModule::FsTurboModule(const ArkTSTurboModule::Context ctx, const std::string name)
88118
: ArkTSTurboModule(ctx, name) {
89119
methodMap_["getConstants"] = MethodMetadata{0, __hostFunction_FsTurboModule_getConstants};
@@ -94,5 +124,11 @@ FsTurboModule::FsTurboModule(const ArkTSTurboModule::Context ctx, const std::str
94124
methodMap_["writeFile"] = MethodMetadata{2, __hostFunction_FsTurboModule_writeFile};
95125
methodMap_["readFileAssets"] = MethodMetadata{1, __hostFunction_FsTurboModule_readFileAssets};
96126
methodMap_["copyFile"] = MethodMetadata{2, __hostFunction_FsTurboModule_copyFile};
97-
methodMap_["unlink"] = MethodMetadata{1, __hostFunction_NativeFsSpecJSI_unlink};
127+
methodMap_["unlink"] = MethodMetadata{1, __hostFunction_FsTurboModule_unlink};
128+
methodMap_["hash"] = MethodMetadata{2, __hostFunction_FsTurboModule_hash};
129+
methodMap_["moveFile"] = MethodMetadata{2, __hostFunction_FsTurboModule_moveFile};
130+
methodMap_["read"] = MethodMetadata{3, __hostFunction_FsTurboModule_read};
131+
methodMap_["write"] = MethodMetadata{3, __hostFunction_FsTurboModule_write};
132+
methodMap_["touch"] = MethodMetadata{3, __hostFunction_FsTurboModule_touch};
133+
methodMap_["stat"] = MethodMetadata{1, __hostFunction_FsTurboModule_stat};
98134
}

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

Lines changed: 163 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,37 @@
2323
*/
2424

2525
import { TurboModule, RNOHError } from 'rnoh/ts';
26-
import fs from '@ohos.file.fs';
26+
import fs, { ReadTextOptions, WriteOptions } from '@ohos.file.fs';
27+
import hash from '@ohos.file.hash';
2728
import { BusinessError } from '@ohos.base';
2829
import common from '@ohos.app.ability.common';
2930
import util from '@ohos.util';
3031
import buffer from '@ohos.buffer';
32+
import HashMap from '@ohos.util.HashMap';
3133

3234
let context = getContext(this) as common.ApplicationContext; // ApplicationContext
3335

36+
interface StatResult {
37+
ctime: number, // The creation date of the file
38+
mtime: number, // The last modified date of the file
39+
size: number, // Size in bytes
40+
mode: number, // UNIX file mode
41+
originalFilepath: string, // ANDROID: In case of content uri this is the pointed file path, otherwise is the same as path
42+
type: number // Is the file just a file? Is the file a directory?
43+
}
44+
3445
export class FsTurboModule extends TurboModule {
35-
// 常量路径
46+
// 常量
3647
getConstants(): object {
3748
return {
3849
// 沙箱路径
3950
FileSandBoxPath: context.filesDir,
4051
// 缓存路径
4152
FileCachePath: context.cacheDir,
53+
// 文件
54+
RNFSFileTypeRegular: 0,
55+
// 文件夹
56+
RNFSFileTypeDirectory: 1,
4257
}
4358
};
4459

@@ -175,4 +190,150 @@ export class FsTurboModule extends TurboModule {
175190
});
176191
})
177192
}
193+
194+
// 文件hash
195+
hash(path: string, algorithm: string): Promise<string> {
196+
return new Promise((resolve, reject) => {
197+
let algorithms: HashMap<string, string> = new HashMap();
198+
algorithms.set('md5', 'md5');
199+
algorithms.set('sha1', 'sha1');
200+
algorithms.set('sha256', 'sha256');
201+
// algorithm不存在
202+
if (!algorithms.hasKey(algorithm)) {
203+
reject('Invalid hash algorithm');
204+
return;
205+
}
206+
// 判断是否是文件夹
207+
let isDirectory = fs.statSync(path).isDirectory();
208+
if (isDirectory) {
209+
reject('file IsDirectory');
210+
return;
211+
}
212+
// 判断文件是否在
213+
let res = fs.accessSync(path);
214+
if (!res) {
215+
reject('file not exists');
216+
return;
217+
}
218+
hash.hash(path, algorithm, (err: BusinessError, result: string) => {
219+
if (err) {
220+
reject("calculate file hash failed with error message: " + err.message + ", error code: " + err.code);
221+
} else {
222+
resolve(result);
223+
}
224+
})
225+
})
226+
}
227+
228+
// 移动文件
229+
moveFile(filepath: string, destPath: string): Promise<void> {
230+
return new Promise((resolve, reject) => {
231+
fs.moveFile(filepath, destPath, 0, (err: BusinessError) => {
232+
if (err) {
233+
reject('move file failed with error message: ' + err.message + ', error code: ' + err.code);
234+
} else {
235+
resolve();
236+
}
237+
})
238+
})
239+
}
240+
241+
// 文件内容部分读
242+
read(path: string, length: number, position: number): Promise<string> {
243+
return new Promise((resolve, reject) => {
244+
let readTextOption: ReadTextOptions = {
245+
offset: position,
246+
length: length,
247+
encoding: 'utf-8'
248+
};
249+
fs.readText(path, readTextOption, (err: BusinessError, str: string) => {
250+
if (err) {
251+
reject('readText failed with error message: ' + err.message + ', error code: ' + err.code);
252+
} else {
253+
let result = buffer.from(str, 'utf8').toString('base64');
254+
resolve(result);
255+
}
256+
});
257+
})
258+
}
259+
260+
// 文件内容从某位置写
261+
write(filepath: string, contents: string, position: number): Promise<void> {
262+
return new Promise((resolve, reject) => {
263+
let result = buffer.from(contents, 'base64').toString('utf8');
264+
let file = fs.openSync(filepath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
265+
let writeOption: WriteOptions = {
266+
offset: position
267+
};
268+
fs.write(file.fd, result, writeOption, (err: BusinessError, writeLen: number) => {
269+
if (err) {
270+
reject('write data to file failed with error message:' + err.message + ', error code: ' + err.code);
271+
} else {
272+
resolve();
273+
}
274+
fs.closeSync(file);
275+
});
276+
})
277+
}
278+
279+
touch(filePath: string, mtime?: number, ctime?: number): Promise<boolean> {
280+
return new Promise((resolve, reject) => {
281+
// 判断是否是文件夹
282+
let isDirectory = fs.statSync(filePath).isDirectory();
283+
if (isDirectory) {
284+
reject('file IsDirectory');
285+
return;
286+
}
287+
// 判断文件是否在
288+
let res = fs.accessSync(filePath);
289+
if (!res) {
290+
reject('No such file or directory');
291+
return;
292+
}
293+
if (mtime) {
294+
try {
295+
fs.utimes(filePath, mtime);
296+
resolve(true)
297+
} catch (err) {
298+
resolve(err.message)
299+
}
300+
} else {
301+
resolve(false)
302+
}
303+
})
304+
}
305+
306+
// 获取文件详细属性信息
307+
stat(filepath: string): Promise<StatResult> {
308+
return new Promise((resolve, reject) => {
309+
let statResult: StatResult = {
310+
ctime: -1,
311+
mtime: -1,
312+
size: -1,
313+
mode: -1,
314+
originalFilepath: '',
315+
type: -1
316+
};
317+
// 判断文件是否在
318+
let res = fs.accessSync(filepath);
319+
if (!res) {
320+
reject('file not exists');
321+
return;
322+
}
323+
fs.stat(filepath, (err: BusinessError, stat: fs.Stat) => {
324+
if (err) {
325+
console.error("error message: " + err.message + ", error code: " + err.code);
326+
} else {
327+
statResult.ctime = stat.ctime;
328+
statResult.mtime = stat.mtime;
329+
statResult.size = stat.size;
330+
statResult.mode = stat.mode;
331+
statResult.originalFilepath = filepath;
332+
statResult.type = stat.isDirectory() ? 1 : 0;
333+
console.log('file statResult: ' + JSON.stringify(statResult));
334+
resolve(statResult);
335+
}
336+
});
337+
})
338+
}
178339
}

src/NativeReactNativeFs..js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,25 @@ type MkdirOptionsT = {
77
NSURLIsExcludedFromBackupKey?: boolean;
88
};
99

10+
type StatResult = {
11+
ctime: number; // The creation date of the file
12+
mtime: number; // The last modified date of the file
13+
size: number; // Size in bytes
14+
mode: number; // UNIX file mode
15+
originalFilepath: string; // ANDROID: In case of content uri this is the pointed file path, otherwise is the same as path
16+
type: number // Is the file just a file? // Is the file a directory?
17+
};
18+
1019
export interface Spec extends TurboModule {
1120
getConstants: () => {
1221
// System paths. 沙箱路径
1322
FileSandBoxPath: string;
23+
// 缓存路径
24+
FileCachePath: string;
25+
// 文件
26+
RNFSFileTypeRegular:number;
27+
// 文件夹
28+
RNFSFileTypeDirectory:number;
1429
};
1530
readFile(path: string): Promise<string>;
1631

@@ -26,7 +41,19 @@ export interface Spec extends TurboModule {
2641

2742
copyFile(from: string, into: string): Promise<void>;
2843

29-
unlink(filepath: string): Promise<void>
44+
unlink(filepath: string): Promise<void>;
45+
46+
hash(filepath: string, algorithm: string): Promise<string>;
47+
48+
moveFile(filepath: string, destPath: string): Promise<void>;
49+
50+
read(path: string, length: number, position: number): Promise<string>;
51+
52+
write(filepath: string, contents: string, position: number): Promise<void>;
53+
54+
stat(filepath: string): Promise<StatResult>;
55+
56+
touch(filepath: string, mtime?: number, ctime?: number): Promise<boolean>;
3057
}
3158

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

0 commit comments

Comments
 (0)