最近使用beta版本系统发现,在部分项目环境下会出现如下异常:
最终通过定位发现是在napi中出现了崩溃,
经过华为技术的支持,最终是由于读取raw文件时候出现了badfd的异常,关闭raw文件操作出现异常如下:
问题原因:closeRawFdSync操作引起的问题,目前还无法定位,初步判断是华为官方系统出现的漏洞在特殊的项目环境下会出现。
// 关闭文件流(问题原因点)
context.resourceManager.closeRawFdSync(name)
inputStream.closeSync();
outputStream.closeSync();
/**
* 初始化文件(流)
*/
public static async initFilesStream(context: Context, name: string): Promise<number> {
if (name == "") {
return -1;
}
let code: number = 1;
try {
await context.resourceManager.getRawFd(name).then(async (value) => {
let fd = value.fd;
let offset = value.offset;
let length = value.length;
let filesDir = context.filesDir;
// 打开文件流
let inputStream = fs.fdopenStreamSync(fd, "r+");
// let inputStream = fs.createStreamSync(filesDir + '/test.txt', 'r+');
let outputStream = fs.createStreamSync(filesDir + '/' + name, "w+");
// 以流的形式读取源文件内容并写入目的文件
let bufSize = value.length;
let readSize = 0;
let buf = new ArrayBuffer(bufSize);
class Option {
public offset: number = 0;
public length: number = bufSize;
}
let option = new Option();
option.offset = value.offset;
if (bufSize > value.length) {
option.length = value.length;
}
let readLen = await inputStream.read(buf, option);
readSize += readLen;
while (readLen > 0) {
await outputStream.write(buf);
option.offset = readSize + value.offset;
option.length = value.length - readSize >= bufSize ? bufSize : value.length - readSize;
readLen = await inputStream.read(buf, option);
readSize += readLen;
}
// 关闭文件流(问题原因点)
context.resourceManager.closeRawFdSync(name)
inputStream.closeSync();
outputStream.closeSync();
code = 0;
})
} catch (error) {
let err = error as BusinessError;
ConsoleUtils.LOG_SDK_ERROR(ConsoleUtils.FILEUTILS, 'Failed to initFilesStream. errorCode = ' + err.code);
code = -1;
}
// await context.resourceManager.getRawFd(name, async (error, value) => {
//
// });
return code;
}
解决方案:
目前采用了resfile方式将文件保存到沙盒,也是比较推荐的方式,不需要自己读写,每次启动app会自动copy到沙盒路径。具体使用方式参考官方文档即可。