Chrome 应用文件阅读器

Chrome App FileReader

我正在尝试在 Chrome 应用程序中使用文件系统 API。我已经尝试了我能找到的所有示例代码,但无法读取简单的文本文件。我几乎记录了每一步,似乎发生(或没有发生)的是我第一次引用文件 reader 对象时一切都停止了。它创建得很好,因为我可以记录 .readyState,但在那之后我似乎甚至无法设置 onload() 事件或执行 .readAsText()。

这是我通过按钮调用的内容:

 function clickButton(){

  chrome.fileSystem.chooseEntry({type: 'openFile', acceptsMultiple: false}, function(FileEntry){
    if(chrome.runtime.lastError) {console.warn("Warning: " + chrome.runtime.lastError.message);}
    else{
      console.log(FileEntry);
      var thing = new FileReader();
      console.log(thing.readyState);
      thing.onloadstart(function(){
        console.log("Started loading " & FileEntry);
      });
      console.log("added onloadstart");
      console.log(thing.readyState);
      console.log(thing);
      thing.readAsText(FileEntry);
      console.log(thing.readyState);
      console.log(thing.result);
    }
  });

  document.getElementById("status").innerHTML = "I did something";
 }

我确实在某处读到 Chrome 不允许访问本地文件,但 chrome 应用程序似乎有所不同。至少,文档似乎暗示了这一点。

我最终在控制台中得到的唯一东西是 FileEntry 对象。

https://developer.chrome.com/apps/app_storage#filesystem

我已经使用了上面的示例代码 link,但仍然无法正确使用。其他人有这个问题或知道我做错了什么吗?

试试这个代码...

<!doctype html>
<html>
<script>
function handle_files(files) {
  for (i = 0; i < files.length; i++) {
    file = files[i]
    console.log(file)
    var reader = new FileReader()
    ret = []
    reader.onload = function(e) {
      console.log(e.target.result)
    }
    reader.onerror = function(stuff) {
      console.log("error", stuff)
      console.log (stuff.getMessage())
    }
    reader.readAsText(file) //readAsdataURL
  }

}
</script>
<body>
FileReader that works!
<input type="file" multiple onchange="handle_files(this.files)">
</body>
</html>

FileEntry 和 File 是有区别的。您需要调用 FileEntry 的 .file() 方法。所以,替换

thing.readAsText(FileEntry);

FileEntry.file(function(File) {
  thing.readAsText(File)
})

https://developer.mozilla.org/en-US/docs/Web/API/FileEntry#File

我编写了一个从文件中提取文本的函数。

  function getFileEntryText(fileEntry) {
    return new Promise(function (resolve, reject) {
      fileEntry.file(function (file) {
        var fileReader = new FileReader();
        fileReader.onload = function (text) {
          resolve(fileReader.result);
        };
        fileReader.onerror = function () {
          reject(fileReader.error);
        };
        fileReader.readAsText(file);
      });
    });
  }

您可以像这样调用此方法:

getFileEntryText(fileEntry).then(function(text) {
      // Process the file text here
}, function(error) {
   // Handle the file error here
});

我在使用文件系统时遇到的一件事是每个调用都是异步的。具有多层嵌套回调会使代码难以阅读。我目前正在通过将我能做的一切转换为 Promise 来解决这个问题。

对于任何有兴趣的人,这里是我的最终(工作)代码,包含我需要遵循所有这些回调的所有 console.log()。

var chosenEntry = null;

 function clickButton(){
    console.log("Button clicked");
    var accepts = [{
      mimeTypes: ['text/*'],
      extensions: ['js', 'css', 'txt', 'html', 'xml', 'tsv', 'csv', 'rtf']
    }];
    chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(theEntry) {
      if (!theEntry) {
        output.textContent = 'No file selected.';
        return;
      }
      // use local storage to retain access to this file
      chrome.storage.local.set({'chosenFile': chrome.fileSystem.retainEntry(theEntry)});
      console.log("local data set.  calling loadFileEntry");
      loadFileEntry(theEntry);
      console.log("loadFileEntry called, returned to clickButton()");
    });
 }

 function loadFileEntry(_chosenEntry) {
  console.log("entered loadFileEntry()");
  chosenEntry = _chosenEntry;
  chosenEntry.file(function(file) {
    readAsText(chosenEntry, function(result) {
      console.log("running callback in readAsText");
      document.getElementById('text').innerHTML = result;
      console.log("I just tried to update textarea.innerHTML");
    });
  });
  console.log("added function to chosenEntry.file()");
 }

function readAsText(fileEntry, callback) {
  console.log("readAsText called");
  fileEntry.file(function(file) {
    var reader = new FileReader();
    console.log("Created reader as FileReader");
    reader.onload = function(e) {
      console.log("called reader.onload function");
      callback(e.target.result);
    };
    console.log("calling reader.readAsText");
    reader.readAsText(file);
  });
}