The File System Access API:根据文件系统API自定义Input Upload

1.前言

先说一下功能需求背景,需要在浏览器端选择文件夹后按遍历文件夹中的所有文件(包含文件夹嵌套文件),项目使用的前端UI组件是React Ant Design,使用Input Upload之后,文件夹可以选取但需要配合action必传字段将文件夹里的所有文件上传后才能预览,并且浏览器Dialog弹出之后显示的“上传”字样,会让用户产生误解,因此开始的调研之路。

2.File System Access API介绍

什么是File System Access API呢?

一开始我也是有点不理解,翻译成中文就是文件系统访问API(在以前被称为Native File System API本地文件系统API,更久之前称为Writeable Files API可写文件API),它可以让开发人员能够开发出特别友好的网络App,能够与用户的本地设备文件进行友好交互,例如集成编辑器,照片和视频编辑软件,文本编辑器等等。在用户授权网站应用后,该文件系统API允许读取和保存用户本地设备文件和文件夹,除此之外文件系统访问 API 还提供了打开目录和枚举其内容的能力。

目前,Windows、macOS、Chrome OS 和 Linux 上的大多数 Chromium 浏览器都支持文件系统访问 API。

3.File System Access API

File System Access API 一共可分为三大类

  • Window.showOpenFilePicker() 打开文件选取窗口
  • Window.showSaveFilePicker() 打开文件保存窗口
  • Window.showDirectoryPicker() 打开文件夹选取窗口

根据需求这里主要使用的Window.showDirectoryPicker()

4.代码示例

<input id='select' type="button" value="选择文件夹">

document.getElementById("select").addEventListener('click', async function onClickHandler(e) {
            try {
                const directoryHandle = await window.showDirectoryPicker({
                    startIn: "desktop"
                });
                const name = directoryHandle.name;
                const files = await listAllFilesAndDirs(directoryHandle, name);
                console.log(files, 'files');
            } catch (e) {
                console.log(e);
            }
        });
        
async function listAllFilesAndDirs(dirHandle, path) {
            const files = [];
            for await (let [name, handle] of dirHandle) {
                const {
                    kind
                } = handle;
                if (handle.kind === 'directory') {
                    const newPath = `${path}/${name}`;
                    files.push(...await listAllFilesAndDirs(handle, newPath));
                } else {
                    // console.log(handle, "name");
                    const file = await handle.getFile();
                    console.log(`${path}/${file.name}`);
                    file.relativePath = `${path}/${file.name}`;
                    if (filterTypes(file)) files.push(file);
                }
            }
            return files;
        }
        
function filterTypes(file, types = ['image/jpeg', 'video/mp4']) {
            if (!files) {
                return false;
            }

            if (types.includes(file.type)) {
                return true;
            }

            return false;

        }

5.总结

这只是本人的一点心得,希望能够和各位大牛~能过够多多交流学习心得,请留下个小心心吧

参考文章:The File System Access API: simplifying access to local files

posted @ 2021-12-07 20:46  小木工  阅读(625)  评论(0编辑  收藏  举报