【问题标题】:Chrome App FileReaderChrome 应用文件阅读器
【发布时间】:2015-06-13 03:21:33
【问题描述】:

我正在尝试在 Chrome 应用中使用文件系统 API。我已经尝试了所有可以找到的示例代码,但无法读取简单的文本文件。我几乎记录了每一步,似乎发生(或没有发生)的是我第一次引用文件读取器对象时一切都停止了。它创建得很好,因为我可以记录 .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

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

【问题讨论】:

    标签: google-chrome-app filereader


    【解决方案1】:

    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

    【讨论】:

    • 这似乎是关键。不仅仅是那个改变,它花了一点(好吧,很多),但它终于奏效了。我正在头晕目眩地追逐我的代码中的所有回调。 :-)
    【解决方案2】:

    试试这个代码...

    <!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>
    

    【讨论】:

    • 没用。 Chrome 应用程序不允许 HTML 中的脚本。 developer.chrome.com/apps/contentSecurityPolicy我把脚本拉成.js文件试试。它对我有点咆哮,因为它不喜欢在循环中定义函数的想法,但它允许我运行它。尽管如此,还是没有结果。控制台日志中没有任何内容。我在 readAsText 之后添加了一行来记录 .readyState,但日志中仍然没有任何内容。
    【解决方案3】:

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

      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 来解决此问题。

    【讨论】:

      【解决方案4】:

      对于任何感兴趣的人,这是我的最终(工作)代码,其中包含我需要遵循所有这些回调的所有 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);
        });
      }
      

      【讨论】:

        猜你喜欢
        • 2011-05-05
        • 1970-01-01
        • 2012-07-17
        • 2017-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多