【问题标题】:Accessing partial results of a FileReader in Firefox在 Firefox 中访问 FileReader 的部分结果
【发布时间】:2014-07-17 17:31:37
【问题描述】:

我想在我的网络应用程序中使用FileReader部分将 CSV 文件加载到浏览器中。但是,我无法在 Firefox 27 中访问 部分结果

我的应用程序只需要 CSV 文件的前 100k 字节来填充数据预览。因此,我设置,启动,然后在加载一定数量的数据后abort阅读器。

这是一个在 Chrome 35 中运行良好的示例:

  warn = (a...) -> console.warn a...
  readFile = (file,cb,limit=1e5) ->
    warn "start reading file..."
    fr = new FileReader
    result = null
    done = -> cb null,result[..limit]
    copy = (e) ->
      if e.target.result? then result = e.target.result; warn "copied #{result.length} bytes"
      else warn "result is empty"
    fr.onloadstart = (e) -> warn "Reading #{file.name} locally..."
    fr.onloadend   = (e) -> warn "Reading finished (end)";   copy(e); done()
    fr.onabort     = (e) -> warn "Reading finished (abort)"; copy(e)
    fr.onload      = (e) -> warn "Reading finished (load)";  copy(e)
    fr.onprogress  = (e) ->
      warn "progress.."; copy(e)
      if e.loaded > limit
        warn "Read #{e.loaded} bytes of CSV file for data preview. Aborting FileReader."
        fr.abort(); fr.onprogress = null
    fr.readAsText file

但是,该代码在 Firefox 中不起作用;中止阅读器时,所有复制的结果都是空的。除了null之外,没有任何事件e带有e.target.result,即使progress事件表明已经读取了一些数据,因为e.loaded设置正确,因此abort()也被触发为预计。

显然 Chrome 和 Firefox 似乎以不同的方式实现 File API,即以不同的方式处理 abort()。在 Firefox 中,您总是必须完全加载文件才能获得任何结果。对我来说,这不合适,因为我的 CSV 文件有 200MB 或更多字节的数据,当我必须完全加载数据时,浏览器会冻结。

PS:我只关心 Chrome 和 FF。 IE 和移动不在此项目的范围内

编辑:这是在 Chrome 和 Firefox 中运行良好的最终解决方案:

  readFile = (file,cb,limit=1e4) ->
    warn "start reading file..."
    fr = new FileReader
    done = (e) ->
      warn "Read #{e.loaded} of #{file.size} bytes of CSV file for data preview"
      cb null,fr.result
    fr.onloadstart = (e) -> warn "Reading #{file.name} locally..."
    fr.onload      = (e) -> warn "Reading finished (load)"; done(e)
    fr.readAsText file.slice 0,limit

【问题讨论】:

    标签: javascript firefox coffeescript filereader fileapi


    【解决方案1】:

    Chrome 违反了当前针对 abort() 的规范草案:

    如果 readyState = LOADING 将 readyState 设置为 DONE 并且 result 为 nullsource,强调我的)

    现在,你可以争论这是好事还是坏事……

    只读部分文件的最佳方法是.slice() File/Blob 对象,然后将其传递给阅读器,告诉浏览器首先只读取文件的一部分:

    fr.readAsText(file.slice(0, limit));
    

    当然,在处理多字节编码(例如 UTF-8)时,您可能需要处理一些问题……但无论如何您都必须处理这些问题,即使您使用 Chrome 专用的 abort() 内容也是如此。

    【讨论】:

    • 谢谢! Blob.slice 成功了。我什至不需要以这种方式手动中止文件加载。
    猜你喜欢
    • 2016-12-25
    • 2017-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多