showDirectoryPicker的getFile()路径超231字符时失效问题
问题
在Windows系统、Chrome 134.0.6998.178(64位)浏览器环境下,使用以下代码遍历目录并读取文件时,当文件的完整路径+文件名长度超过231字符,调用getFile()会抛出错误:
async function getFilesHandles(dirHandle) { const handles = []; for await (const entry of dirHandle.values()) { if (entry.kind === 'directory') { handles.push(...(await getFilesHandles(entry))); } else { handles.push(entry); } } return handles; } const directoryHandle= await window.showDirectoryPicker({ mode: 'read' }); const handles = await getFilesHandles(directoryHandle); await handles[0].getFile(); // 路径+文件名长度>231字符时失效
抛出的错误信息:
Uncaught NotFoundError: A requested file or directory could not be found at the time an operation was processed.
查阅File System Access API规范文档后,未找到该长度限制的相关说明,请问有可行的解决办法吗?
解决办法
这个问题源于Windows系统底层的传统路径长度限制(MAX_PATH相关机制),Chrome的File System Access API在Windows平台调用系统原生API时触发了该限制,以下是几种可行的解决方案:
- 基于根目录句柄的相对路径读取:不直接存储深层文件的
FileSystemFileHandle,而是记录文件相对于根目录的路径,读取时从根目录句柄逐层导航到目标文件,再调用getFile()。示例代码:
async function getFileRelPaths(dirHandle, parentPath = '') { const relPaths = []; for await (const entry of dirHandle.values()) { const currentPath = parentPath ? `${parentPath}/${entry.name}` : entry.name; if (entry.kind === 'directory') { relPaths.push(...(await getFileRelPaths(entry, currentPath))); } else { relPaths.push(currentPath); } } return relPaths; } async function getFileByRelPath(rootDir, relPath) { const pathSegments = relPath.split('/'); let currentDir = rootDir; // 逐层进入目录 for (let i = 0; i < pathSegments.length - 1; i++) { currentDir = await currentDir.getDirectoryHandle(pathSegments[i]); } // 获取文件句柄并读取 const fileHandle = await currentDir.getFileHandle(pathSegments.at(-1)); return await fileHandle.getFile(); } // 使用示例 const rootDirHandle = await window.showDirectoryPicker({ mode: 'read' }); const fileRelPaths = await getFileRelPaths(rootDirHandle); const targetFile = await getFileByRelPath(rootDirHandle, fileRelPaths[0]);
缩短路径长度:直接修改过长的目录名或文件名,减少整体路径的字符数,避开Windows的路径限制。
启用Windows长路径支持:若用户环境允许,可引导用户开启Windows系统的长路径支持(通过修改组策略或注册表),系统层面解除路径长度限制后,Chrome的API调用即可正常处理长路径文件。
内容的提问来源于stack exchange,提问作者Mustapha Aouas
相关产品推荐
相关产品推荐

