问题 : 前端需要解压 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 为一个二进制文件,下载地址
运行结果:
- 将结果处理成 tree 型结构,代码演示:
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函数处理之后的结果
运行结果: