文件操作利器: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>
相关推荐
JarvanMo4 分钟前
终极指南:在 Flutter 中通过 sign_in_with_apple 实现 Apple 登录
前端
Learner10 分钟前
Python异常处理
java·前端·python
tao35566714 分钟前
VS Code登录codex,报错(os error 10013)
java·服务器·前端
军军君0117 分钟前
Three.js基础功能学习七:加载器与管理器
开发语言·前端·javascript·学习·3d·threejs·三维
哈__18 分钟前
React Native 鸿蒙开发:内置 Share 模块实现无配置社交分享
javascript·react native·react.js
JarvanMo20 分钟前
情迷服务器驱动 UI:我在 Flutter 开发中的爱与哀愁
前端
tzy23322 分钟前
分享一个 HTTP(S) 代理&抓包工具,拦截和Mock Web客户端请求和服务端响应
前端·网络协议·http
代码小学僧28 分钟前
普通前端仔的 2025 : 年终总结与 AI 对我的影响
前端·程序员·ai编程
Mike_jia34 分钟前
TCP 粘包/拆包问题
前端
沐墨染41 分钟前
敏感词智能检索前端组件设计:树形组织过滤与多维数据分析
前端·javascript·vue.js·ui·数据挖掘·数据分析