文件操作利器:showOpenFilePicker

概述

在传统的前端开发中,处理用户文件一直是个棘手的问题。虽然 <input type="file"> 提供了基本的文件选择功能,但当需要处理整个目录结构时,开发者往往需要借助复杂的后端支持或Electron等桌面框架。showDirectoryPicker() 的出现彻底改变了这一局面,它为Web应用提供了原生的目录访问能力,文件操作体验。

showDirectoryPicker

showDirectoryPicker() 是 File System Access API 的核心方法之一,它允许Web应用通过用户授权的方式访问整个目录结构,而不仅仅是单个文件。这意味着开发者现在可以在浏览器中实现以前只能在桌面应用中才能完成的文件操作。

核心特性

  • 完整的目录访问:读取、遍历、修改目录内容
  • 权限持久化:用户授权后可保存访问权限
  • 安全沙箱:在严格的用户控制下运行
  • 现代化API:基于Promise的异步设计

浏览器支持情况

只有部分浏览器支持,并且版本比较新,希望以后能够更好支持

基础使用与语法

基本调用方式

js 复制代码
async function selectDirectory() {
  try {
    const directoryHandle = await window.showDirectoryPicker();
    console.log('选择的目录:', directoryHandle.name);
    return directoryHandle;
  } catch (err) {
    if (err.name === 'AbortError') {
      console.log('用户取消了选择');
    } else {
      console.error('发生错误:', err);
    }
  }
}

配置选项

js 复制代码
const options = {
  id: 'projectFolder', // 标识符,用于记住用户选择
  mode: 'readwrite',   // 权限模式:read 或 readwrite
  startIn: 'documents' // 起始目录:desktop, documents, downloads等
};

const directoryHandle = await showDirectoryPicker(options);

权限模式

  • read :仅读取权限,可以列出文件和读取内容
  • readwrite :读写权限,可以创建、修改、删除文件

实际应用场景

遍历文件内容

js 复制代码
async function* walkDirectory(directoryHandle, path = '') {
  for await (const entry of directoryHandle.values()) {
    const entryPath = `${path}/${entry.name}`;
    
    if (entry.kind === 'directory') {
      yield* await walkDirectory(entry, entryPath);
    } else {
      yield {
        handle: entry,
        path: entryPath,
        kind: 'file'
      };
    }
  }
}

// 使用示例
async function printDirectoryTree() {
  const directoryHandle = await showDirectoryPicker();
  
  for await (const entry of walkDirectory(directoryHandle)) {
    console.log(entry.path);
  }
}

printDirectoryTree()

解析本地文件夹可视化到线上

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <button>打开文件</button>


    <script>

        const btn = document.querySelector('button');

        btn.addEventListener('click', async () => {
            const fileHandles = await showDirectoryPicker();

            await processHandle(fileHandles);


            console.log("fileHandles----", fileHandles);

            processFile(fileHandles);

            async function processHandle(handle) {
                if (handle.kind === 'file') {
                    return
                }
                const iter = handle.entries();
                handle.children = []
                for await (const [name, childHandle] of iter) {
                    handle.children.push(childHandle);
                    processHandle(childHandle);
                }
            }



            async function processFile(fileHandles) {

                if (fileHandles.kind === 'file') {
                    const file = await fileHandles.getFile();
                    console.log("file----", file);
                    const fileReader = new FileReader();

                    fileReader.onload = (e) => {
                        console.log("fileReader.result---", e.target.result);
                    }

                    fileReader.readAsText(file);
                } else {
                    for (let i = 0; i < fileHandles.children.length; i++) {
                        const childHandle = fileHandles.children[i];
                        processFile(childHandle);
                    }
                }


            }
        });
    </script>
</body>

</html>
相关推荐
WooaiJava8 小时前
AI 智能助手项目面试技术要点总结(前端部分)
javascript·大模型·html5
爱喝白开水a8 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
Never_Satisfied8 小时前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
董世昌418 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
WeiXiao_Hyy9 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡10 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone10 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_090110 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农10 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king11 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落