OpenHarmony开发者论坛
标题:
OpenHarmony 应用如何使用@ohos.worker多线程进行批量文件读写与复制
[打印本页]
作者:
深开鸿_苟晶晶
时间:
2024-1-19 16:17
标题:
OpenHarmony 应用如何使用@ohos.worker多线程进行批量文件读写与复制
[md]# OpenHarmony 应用如何使用@ohos.worker多线程进行批量文件读写与复制
## 简介:
支持批量文件读写、复制等操作,支持使用@ohos.worker进行多线程开发。创先线程可以使用[@ohos.worker](
https://gitee.com/openharmony/do ... s/js-apis-worker.md
)
## 文档环境:
* 开发环境:Windows 11 家庭版
* DevEco Studio版本:DevEco Studio 4.0 Release(4.0.0.600)
* SDK版本:4.0.10.13
* 开发板型号:DAYU200(RK3568)
* 系统版本:OpenHarmony 4.1.5.2
## 演示 demo:
* 新建一个 Stage 框架的 demo 工程,在entryability/EntryAbility.ets中通过 let filesDir = this.context.filesDir;AppStorage.SetOrCreate('sanBoxFileDir', filesDir);存储沙箱files路径信息,然后在pages/CopyFile.ets中通过public baseDir: string | undefined = AppStorage.Get('sanBoxFileDir');拿到应用的沙箱files路径信息,通过文件操作接口在files下创建文件夹workerDir并创建以txt为后缀的文件。
* 通过接口fs.listFileSync(filesPathDir)获取workerDir文件夹下的所有文件并显示在list中。
* 用户点击多选框选择需要批量拷贝的文件,通过new worker.ThreadWorker('entry/ets/workers/WorkerCopy.ets')创建worker线程并将拷贝文件的信息发送至worker线程,在该线程中通过fs.copyFileSync(srcPath, destPath)实现文件拷贝操作,文件拷贝成功之后向主线程发送拷贝成功消息:workerPort.postMessage({count: count,strFlag: true,listFileNames: listFileNames});
核心代码如下:
在沙箱路径下创建待拷贝的文件:
```
readyFilesToWorker(): void {
let content = CONTENT + CONTENT + new Date() + '\n';
let workerDir = this.baseDir + '/workerDir';
try {
if (!fs.accessSync(workerDir)) {
fs.mkdirSync(workerDir);
}
Logger.info(TAG, 'readyFilesToWorker dpath = ' + workerDir);
for (let i = 0; i < FILE_NUM; i++) {
let myFile = '';
if (i < FILE_NUMBER) {
myFile = workerDir + `/TestFile0${i + 1}.txt`;
} else {
myFile = workerDir + `/TestFile${i + 1}.txt`;
}
Logger.info(TAG, 'readyFilesToWorker myFile = ' + myFile);
let file = fs.openSync(myFile, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
fs.writeSync(file.fd, content);
fs.closeSync(file);
}
Logger.info(TAG, 'readyFilesToWorker successful');
} catch (e) {
Logger.error(TAG, `readyFilesToWorker has failed for: {message: ${(e as BusinessError).message}, code: ${(e as BusinessError).code}}`);
}
}
```
创建worker线程并发送拷贝的文件信息:
```
async workToCopyFiles(files: Array<string>, filePath: string): Promise<void> {
try {
Logger.info(TAG, 'WorkCreator start to create worker');
let destPath = filePath;
Logger.info(TAG, 'Workerets destPath ' + destPath);
if (!fs.accessSync(destPath)) {
fs.mkdirSync(destPath);
}
if (fs.accessSync(destPath)) {
fs.listFile(destPath).then((filenames) => {
Logger.info(TAG, 'listFile succeed');
for (let i = 0; i < filenames.length; i++) {
Logger.info(TAG, 'Workerets fileName: ' + filenames
);
}
}).catch((err: BusinessError) => {
Logger.info(TAG, 'list file failed with error message: ' + err.message + ', error code: ' + err.code);
});
}
if (files !== null) {
this.realFileNames.length = 0;
for (let i = 0; i < files.length; i++) {
if (files
=== 'deletedTag') {
continue;
}
this.realFileNames.push(files
);
}
}
let count = this.realFileNames.length;
for (let j = 0; j < count; j++) {
Logger.info(TAG, 'workToCopyFiles this.realFileNames = ' + this.realFileNames[j]);
}
workerInstance = new worker.ThreadWorker('entry/ets/workers/WorkerCopy.ts');
if (this.realFileNames !== null) {
let srcPath = this.baseDir + '/workerDir';
workerInstance.postMessage({
srcDir: srcPath,
destDir: destPath,
fileNames: this.realFileNames
});
}
workerInstance.onexit = (code): void => {
Logger.info(TAG, `workerInstance::onexit has been exit ${code}`);
};
workerInstance.onerror = (err): void => {
Logger.info(TAG, `workerInstance::onerror has errors: ${JSON.stringify(err)}`);
};
workerInstance.onmessageerror = (event): void => {
Logger.info(TAG, `workerInstance::onmessageerror has errors: ${JSON.stringify(event)}`);
};
workerInstance.onmessage = (message): void => {
Logger.info(TAG, `workerInstance::onmessage receive data: ${JSON.stringify(message.data)}`);
if (message.data.hasOwnProperty('count')) {
Logger.info(TAG, `workerInstance::onmessage receive data length = ${message.data.count}`);
this.filesCount = message.data.count;
fileFlag = message.data.strFlag;
this.flag = true;
let fileName1: string | null = null;
let fileName2: string | null = null;
for (let i: number = 0; i < message.data.listFileNames.length; i++) {
Logger.info(TAG, `Worker workerInstance::onmessage receive listFileNames: ${message.data.listFileNames
}`);
}
if (message.data.listFileNames[0] !== undefined && message.data.listFileNames[1] !== undefined && message.data.listFileNames[LIST_FILE_TWO] === undefined) {
fileName1 = message.data.listFileNames[0] + '、';
fileName2 = message.data.listFileNames[1];
} else if (message.data.listFileNames[0] !== undefined && message.data.listFileNames[1] === undefined) {
fileName1 = message.data.listFileNames[0];
fileName2 = '';
} else {
fileName1 = message.data.listFileNames[0] + '、';
let copyFileLog: string | undefined = AppStorage.Get('copyFileLog5');
fileName2 = message.data.listFileNames[1] + copyFileLog;
}
AppStorage.SetOrCreate('fileListName1', fileName1);
AppStorage.SetOrCreate('fileListName2', fileName2);
let copyFileLog3: string | undefined = AppStorage.Get('copyFileLog3');
let copyFileLog4: string | undefined = AppStorage.Get('copyFileLog4');
let copyFileLog = '2、' + fileName1 + fileName2 + copyFileLog3 + 'copy' + copyFileLog4;
if (fileName1 !== 'undefined、') {
AppStorage.SetOrCreate('copyFileShowLog', copyFileLog);
} else {
AppStorage.SetOrCreate('copyFileShowLog', $r('app.string.workerLogChooseFile'));
}
Logger.info(TAG, `Worker workerInstance::onmessage receive count: ${JSON.stringify(this.filesCount)}`);
}
if (this.filesCount !== 0) {
AppStorage.SetOrCreate('fileNumber', JSON.stringify(this.filesCount));
} else {
AppStorage.SetOrCreate('fileNumber', '0');
AppStorage.SetOrCreate('fileListName1', '');
AppStorage.SetOrCreate('fileListName2', '');
}
Logger.info(TAG, 'workerInstance::onmessage Finish to process data from WorkerCopy.ts');
workerInstance?.terminate();
};
while (!fileFlag) {
await sleep(SLEEP_TIME);
}
} catch (e) {
Logger.error(TAG, `Worker WorkCreator error package: message: ${(e as BusinessError).message}, code: ${(e as BusinessError).code}`);
}
}
```
worker线程实现拷贝:
```
import worker from '@ohos.worker';
import type { ThreadWorkerGlobalScope } from '@ohos.worker';
import Logger from '../common/Logger';
import fs from '@ohos.file.fs';
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
const TAG: string = '[ConcurrentModule].[WorkerCopy]';
workerPort.onmessage = (message): void => {
let srcPath: string = null;
let destPath: string = null;
let fileNames: string = message.data.fileNames;
for (let i = 0; i < fileNames.length; i++) {
srcPath = message.data.srcDir + '/' + fileNames
;
Logger.info(TAG, ' srcPath ' + srcPath);
destPath = message.data.destDir + '/' + fileNames
;
Logger.info(TAG, ' destPath ' + destPath);
try {
fs.copyFileSync(srcPath, destPath);
let countTest = fs.listFileSync(message.data.destDir).length;
Logger.info(TAG, `Worker workerInstance::onmessage receive countTest: ${countTest}`);
} catch (e) {
Logger.error(TAG, 'WorkerCopy::copyFile has failed for: ' + JSON.stringify(e));
}
}
let listFileNames = [];
listFileNames.length = 0;
try {
let count = fs.listFileSync(message.data.destDir).length;
let listFiles = fs.listFileSync(message.data.destDir);
Logger.info(TAG, 'listFile succeed');
for (let i = 0; i < listFiles.length; i++) {
listFileNames
= listFiles
;
Logger.info(TAG, `Worker workerInstance::onmessage receive listFileNames: ${listFileNames
}`);
}
workerPort.postMessage({
count: count,
strFlag: true,
listFileNames: listFileNames
});
Logger.info(TAG, 'WorkerCopy::onmessage thread post message successfully');
} catch (e) {
Logger.error(TAG, 'WorkerCopy::onmessage has failed for: ' + JSON.stringify(e));
}
};
workerPort.onmessageerror = async (message): Promise<void> => {
Logger.error(TAG, 'WorkerCopy::onmessageerror : ' + JSON.stringify(message));
};
workerPort.onerror = (e): void => {
Logger.error(TAG, 'WorkerCopy::onerror : ' + JSON.stringify(e));
};
```
[/md]
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5