蛊毒传说
不幸的是,现有答案中没有一个是完全正确的,因为readEntries不一定会返回给定目录的所有(文件或目录)条目。这是API规范的一部分(请参见下面的文档部分)。为了真正获取所有文件,我们需要readEntries重复调用(对于遇到的每个目录),直到它返回一个空数组。如果不这样做,我们将丢失目录中的某些文件/子目录(例如在Chrome中),readEntries一次最多只能返回100个条目。使用Promises(await/ async)可以更清楚地演示readEntries(因为它是异步的)的正确用法,并使用广度优先搜索(BFS)遍历目录结构:// Drop handler function to get all filesasync function getAllFileEntries(dataTransferItemList) { let fileEntries = []; // Use BFS to traverse entire directory/file structure let queue = []; // Unfortunately dataTransferItemList is not iterable i.e. no forEach for (let i = 0; i < dataTransferItemList.length; i++) { queue.push(dataTransferItemList[i].webkitGetAsEntry()); } while (queue.length > 0) { let entry = queue.shift(); if (entry.isFile) { fileEntries.push(entry); } else if (entry.isDirectory) { queue.push(...await readAllDirectoryEntries(entry.createReader())); } } return fileEntries;}// Get all the entries (files or sub-directories) in a directory // by calling readEntries until it returns empty arrayasync function readAllDirectoryEntries(directoryReader) { let entries = []; let readEntries = await readEntriesPromise(directoryReader); while (readEntries.length > 0) { entries.push(...readEntries); readEntries = await readEntriesPromise(directoryReader); } return entries;}// Wrap readEntries in a promise to make working with readEntries easier// readEntries will return only some of the entries in a directory// e.g. Chrome returns at most 100 entries at a timeasync function readEntriesPromise(directoryReader) { try { return await new Promise((resolve, reject) => { directoryReader.readEntries(resolve, reject); }); } catch (err) { console.log(err); }}Codepen上的完整工作示例:https ://codepen.io/anon/pen/gBJrOPFWIW我之所以选择它,是因为在使用接受的答案时,我没有找回包含40,000个文件的目录(许多目录包含100多个文件/子目录)的所有文件。说明文件:FileSystemDirectoryReader中记录了此行为。重点摘录:readEntries()返回一个包含一些 目录条目的数组。数组中的每个项目都是基于FileSystemEntry的对象,通常是FileSystemFileEntry或FileSystemDirectoryEntry。但公平地说,MDN文档可以在其他部分中使这一点更加清楚。该readEntries()文件只是指出:readEntries()方法检索正在读取的目录中的目录条目,并将它们以数组形式传递给提供的回调函数并且唯一需要多次调用的提示是在successCallback参数的描述中:如果没有剩余文件,或者您已经在此FileSystemDirectoryReader上调用了readEntries(),则该数组为空。可以说该API也可以更加直观,但是如文档所述:它是一项非标准/实验性功能,不在标准轨道上,并且不能指望所有浏览器都可以使用。有关:johnozbay评论说,在Chrome上,readEntries一个目录(验证为Chrome 64)最多返回100个条目。XanreadEntries很好地解释了此答案的正确用法(尽管没有代码)。PabloBarríaUrenda的答案可以readEntries在没有BFS的情况下以异步方式正确调用。他还指出,Firefox返回目录中的所有条目(与Chrome不同),但是给定规范,我们不能依靠它。