问题 : 前端需要解压 rar 压缩包并生成 tree 的数据格式
解决办法 : 使用 node-unrar-js 插件,具体步骤如下
安装包npm i node-unrar-js@2.0.0
引入 import { createExtractorFromData, UnrarError } from 'node-unrar-js';
解压 rar 代码演示: methods: {getRARMetadata(file) { return new Promise((resolve, reject) => { const reader = new FileReader() var fileList = []; reader.onload = async () => { const data = reader.result; const wasmBinary = await ( await fetch(`../unrar.wasm`, { credentials: 'same-origin' }) ).arrayBuffer(); const extractor = await createExtractorFromData({ wasmBinary, data }); const { arcHeader, fileHeaders } = extractor.getFileList(); for (const fileHeader of fileHeaders) { fileList.push(fileHeader) } resolve(fileList) }; reader.onerror = error => { reject(error); }; reader.readAsArrayBuffer(file); }); },}
注: getRARMetadata(file) 参数 file 为上传文件之后获取的 file.raw; unrar.wasm 为一个二进制文件,下载地址
运行结果:
buildRarTree(treeData) { const tree = [] let filterTreeData = treeData.reverse() filterTreeData.reverse().forEach((path, i) => { const segments = path.name.split('/') let currentNode = tree; segments.forEach((segment, index) => { const isLastSegment = index === segments.length - 1 const isDir = path.flags.directory if (segment !== '') { // Filter out nodes with empty labels let existingNode = currentNode.find(node => node.label === segment) let size = 0 if (!existingNode) { const filePath = path.name.slice(0,path.name.lastIndexOf('/')) const newNode = { uploadFilePath: `${i}${index}` == '00' ? segment : isLastSegment ? path.name : filePath, label: segment, size: isLastSegment ? path.unpSize : 0, id: i + '' + index, data: path.time, dir: isLastSegment ? isDir : true, type: 2, forUUIDPath: this.offlineImportParams.url, md5: h_md5(`${path.unpSize}${path.name}${path.crc}${path.time}`), } if (isLastSegment) { newNode.label = segment } else { newNode.children = [] } currentNode.push(newNode) existingNode = newNode } currentNode = existingNode.children } }) }) return tree },
注: treeData为getRARMetadata函数处理之后的结果
运行结果: