鸿蒙 大文件分片下载遇内存限制问题
arkts大文件分片下载
·
interface hadChunkProps {
cur: number
file: ArrayBuffer
}
接口请求获得文件分片结果,推入数组后获得chunkArr,对数组排序;
之前的方法是:
try {
const blobFile = new buffer.Blob(sortChunks.map((item) => item.file), { type: 'application/octet-stream' } as ESObject)
const ab = await blobFile.arrayBuffer()
let file = await fs.open(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
logUtil.info(['new File: ', JSON.stringify(file)]);
try {
const writeLen = await fs.write(file.fd, ab);
logUtil.info(["write data to file succeed and size is:", writeLen.toString()]);
} catch (err){
logUtil.error(['Error in file creation or writing 1: ', err.message]);
}
finally {
fs.closeSync(file);
}
return filePath;
} catch (error) {
logUtil.error(['Error in file creation or writing 2: ', error.message]);
return '';
但此方法会与较小文件(约30MB以下)无问题,若文件再大一些出现报错:
OutOfMemory when trying to allocate 209715224 bytes function name: Heap::AllocateHugeObject Cannot get SourceMap info, dump raw stack
故使用文件流处理文件下载:
let curSize: number = 0
let file1 = fs.openSync(filePath,fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE) //注意不能对同一文件重复修改!!! =>分片下载时可对同名文件做断点续传
const stream1 = await fs.fdopenStream(file1.fd,"a+")
for (let chunk of sortChunks){
let option : WriteOptions = {
length:chunk.file.byteLength,
offset:curSize
}
const num:number = stream1.writeSync(chunk.file, option)
console.log(`片段${chunk.cur}终索引:`,curSize,'-',num)
curSize += num
}
stream1.close();
return filePath
方法使用不难,但花费了半天时间处理出问题没找到原因,最后发现原因在于中间文件(file1:存放沙箱,下载过渡用)在下载完成后需要删除,否则遇同名文件会对该文件进行写入流处理,导致测试下载的文件始终大于源文件。
额外问题:
1.文件覆盖写入问题:待覆盖的文件内容长度比原内容短,会导致新内容长度以后的缓存区维持原内容,所以要截断后续多与内容:
async save() {
try{
// 保存时加文件锁处理并发
logUtil.info(['chartRecord save: ', this.fileUrl])
const file = await fs.open(this.fileUrl, fs.OpenMode.WRITE_ONLY | fs.OpenMode.CREATE) //只写:清空原内容
file.tryLock(true); //共享锁 ==》13900010,文件暂不可用
// const buf = buffer.from(JSON.stringify(this.records),'utf-8')
// console.log('待写入的缓冲区长度:',buf.length)
fs.write(file.fd, JSON.stringify(this.records)).then((writeLen: number) => {
fs.truncateSync(file.fd,writeLen)
}).catch((err: BusinessError) => {
}).finally(() => {
file.unlock(); //解锁
fs.closeSync(file);
});
}catch(e){
}
}
更多推荐



所有评论(0)