readAsText(file) 只读取目录中的最后一个文件

readAsText(file) only reads the last file in a directory

我正在尝试读取用户目录中的所有文件并将其内容显示在文本框中。

读取单个文件效果很好,但是,当我尝试读取整个目录时,事情变得很奇怪。

遍历目录时,只有目录中的最后一个文件被正确读取。无论目录中有多少文件,此行为都是一致的。

这是我用来读取文件的代码:

results.forEach(function(item) {
  reader = new FileReader();

  // This line is reached
  console.log("filename: " + item.name);

  item.file(function(File) {
    // This one only for the last file in that directory
    reader.readAsText(File);
    console.log("success");
  });

  // This line is reached
  console.log("read: " + item.name);
});

这是日志(来自开发工具):

filename: app.js
read: app.js
filename: main.js
read: main.js
filename: SharedPreferences.js
read: SharedPreferences.js
filename: KeyConstants.js
read: KeyConstants.js
success

如果您有任何问题,请问他们,我已经尝试了几个小时了,我已经厌倦了一次又一次的失败..

发生这种情况是因为FileReader 异步工作,这大约意味着它开始执行任务(读取文件),同时继续执行代码。如果你想在加载完成后立即对每个文件的结果做些什么,你需要使用这个方法:

reader.onloadend = function(evt) {
    // file is loaded
    // do something with evt.target object
};

我最终的解决方案:

就像 abcdn 所说的那样,问题是我用一个新的覆盖了 reader。

我通过使用 javascript 闭包解决了这个问题(我不知道它存在,因为我来自 C#)。

这是我最后使用的完整代码:

chrome.fileSystem.chooseEntry({type: "openDirectory"}, function(dir) {
  readFolderAsArrayBuffer(dir, function() {
    console.log("read folder");
  });
});


function readFolderAsArrayBuffer(dir, callback) {
  if (dir && dir.isDirectory) {
    var reader = dir.createReader();
    var handlefile = function (entries) {
      for (var i = 0; i < entries.length; i++) {
        arr[i] = (function(fileEntry, number) {
          console.log("returning function " + number);
          entries[number].file(function(file) {
            handleread(fileEntry, file);
            console.log("reading" + url);
          });
        })(entries[i], i);
      }
    }

    var handleerror = function() {
      console.log("error");
    };
    reader.readEntries(handlefile, handleerror);
  }
}

var handleread = function(fileEntry, file) {
  var fileReader = new FileReader();
  fileReader.onloadend = function(evt) {
    console.log("Read file: " + fileEntry.name + "with the content: " + evt.target.result);
  };
  fileReader.readAsText(file);
}

这会读取整个用户选择的目录并将每个文件的内容输出到控制台。