插件窝 干货文章 如何利用webkitRelativePath属性还原扁平文件列表为带有文件夹层级结构的树形结构?

如何利用webkitRelativePath属性还原扁平文件列表为带有文件夹层级结构的树形结构?

文件 file 结构 树形 472    来源:    2025-03-20

要将扁平的文件列表还原为带有文件夹层级结构的树形结构,可以利用 webkitRelativePath 属性。webkitRelativePath<input type="file" webkitdirectory> 选择的文件中的一个属性,它表示文件相对于所选文件夹的相对路径。

以下是一个示例代码,展示如何将扁平的文件列表转换为树形结构:

function buildFileTree(files) {
    const root = {};

    files.forEach(file => {
        const pathParts = file.webkitRelativePath.split('/');
        let currentLevel = root;

        pathParts.forEach((part, index) => {
            if (!currentLevel[part]) {
                currentLevel[part] = {};
            }

            if (index === pathParts.length - 1) {
                currentLevel[part] = file; // 文件
            } else {
                currentLevel = currentLevel[part]; // 文件夹
            }
        });
    });

    return root;
}

// 示例使用
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (event) => {
    const files = Array.from(event.target.files);
    const fileTree = buildFileTree(files);
    console.log(fileTree);
});

代码解释:

  1. buildFileTree 函数

    • 该函数接受一个文件列表 files 作为输入。
    • 初始化一个空对象 root 作为树的根节点。
    • 遍历每个文件,根据 webkitRelativePath 属性将文件路径拆分为多个部分。
    • 使用这些路径部分逐步构建树结构。如果路径部分不存在,则创建一个新的对象来表示文件夹或文件。
  2. fileInput 事件监听器

    • 当用户选择文件夹时,change 事件被触发。
    • 获取选择的文件列表,并将其传递给 buildFileTree 函数。
    • 最终生成的树形结构存储在 fileTree 中,并打印到控制台。

示例输出:

假设用户选择的文件夹结构如下:

folder/
    subfolder/
        file1.txt
        file2.txt
    file3.txt

生成的树形结构可能如下:

{
    "folder": {
        "subfolder": {
            "file1.txt": File { ... },
            "file2.txt": File { ... }
        },
        "file3.txt": File { ... }
    }
}

注意事项:

  • webkitRelativePath 是 WebKit 特有的属性,因此在非 WebKit 浏览器中可能不可用。
  • 该代码假设所有文件路径都是有效的,并且没有重复的文件名。

通过这种方式,你可以将扁平的文件列表还原为带有文件夹层级结构的树形结构,便于进一步处理或展示。