在应用 Node.js 合并文件分片时呈现了题目的错误信息。
代码剖析
m.merge = (opts) => { return new Promise((resolve, reject) => { const { filename, target } = opts; try { let len = 0; const bufferList = fs.readdirSync(`${STATIC_TEMPORARY}/${filename}`).map((hash, index) => { const buffer = fs.readFileSync(`${STATIC_TEMPORARY}/${filename}/${index}`); len += buffer.length; return buffer; }); // Merge files const buffer = Buffer.concat(bufferList, len); const ws = fs.createWriteStream(`${target}/${filename}`); ws.write(buffer); ws.close(); resolve({ success: true, msg: 'Section merge completed' }); } catch (error) { console.error(error); reject({ success: false, msg: error }); } });};
const buffer = Buffer.concat(bufferList, len);
定位到是上边这行呈现了问题,查看了一下服务器,node利用的内存占用是 192.1mb。
这时起因就很明了,是因为文件分片太大导致内存耗尽,没有可用空间了。
优化办法
下面的做法是把所有的文件分片都concat而后写到流中,正是在这个过程中导致了内存耗尽。
其实,咱们能够按程序分屡次concat写入,批改代码如下:
m.merge = (opts) => { return new Promise((resolve, reject) => { const { filename, target } = opts; try { // 优化 const ws = fs.createWriteStream(`${target}/${filename}`); const bufferList = fs.readdirSync(`${STATIC_TEMPORARY}/${filename}`) let len = 0; let list = [] bufferList.forEach((hash, index) => { const b = fs.readFileSync(`${STATIC_TEMPORARY}/${filename}/${index}`); len += b.length; list.push(b) if (len > 10485760) { // 10M const buffer = Buffer.concat(list, len); ws.write(buffer); len = 0; list = [] } }) ws.close(); resolve({ success: true, msg: 'Section merge completed' }); } catch (error) { console.error(error); reject({ success: false, msg: error }); } });};
这是从新调用接口就不会呈现题目的谬误了,文件能够合并胜利。然而查看一下Node过程的内存占用 却依然放弃在192.1mb左右。
这就须要对Node做一下具体的内存剖析了。