【问题标题】:HTML5 Binary File Writing w/ Base64使用 Base64 编写 HTML5 二进制文件
【发布时间】:2011-12-07 07:46:18
【问题描述】:

如您所知,HTML 5 提供了一个不错的 FileAPI。我建立了一个系统,用户接收 Base64 编码的字符串,需要写入磁盘(具有适当的权限,因为它是 Google Chrome 应用程序)。我的代码如下:(清除一些不必要的东西)

function onInitFs(fs){      
  fs.root.getFile(fileName, {create: true}, function(fileEntry) {
    fileEntry.createWriter(function(fileWriter) {
      var bb = new window.WebKitBlobBuilder(); 
      bb.append( atob(dataInBase64Format));
      fileWriter.write(bb.getBlob());           
    }, errorHandler);
    console.log( fileEntry.toURL());
  }, errorHandler);
}

但是,我的原始文件大小是:6302446 字节,服务器将它们作为 Base64 以 8403264 字节发送,但保存的文件是 9242715 字节。当然,我知道出了点问题,我查看了文件,它只是一个不错的字符串。没有花哨的字符出现。我假设我以文本模式编写,而 atob 只是将其转换为另一个字符串;我需要将其转换为二进制格式(也许是数组?)并强制我的 fileWriter 以二进制模式而不是文本模式写入。我在网上搜索过,但找不到解决方案。我在 StackOverflow Are Google Chrome Base64 methods capable of handling binary data from the File API? 上找到了这个问题,但对我没有帮助。

如何将我的 Base64 字符串转换为正确的数据结构并让我的 fileWriter 来编写它?

【问题讨论】:

  • 我也遇到了这个问题。我在 Blob 规范中找到了原因:w3c.github.io/FileAPI/#blob。它会尝试将您提供的任何 DOMStrings 重新编码为 UTF-8。这也会导致字符串中的无效 Unicode 字符被 U+FFFD 替换字符替换。显然,这会对您尝试添加的二进制数据造成非常不利的影响。

标签: javascript html google-chrome blob fileapi


【解决方案1】:

我编写了一个扩展程序,它使用 Chrome 捕获屏幕截图,将其放在画布上,调整其大小,然后使用 Filesystem API 保存画布数据。不确定这是否与您的直接相似,但也许大部分代码就足够了吗?

在这种情况下,我假设我的dataURI(例如myCanvas.toDataURL("image/png"))与dataInBase64Format 的Base64 格式相同。

功能:

// canvas.toBlob is not implemented in Chrome yet! So we have to build the blob ourselves.
// Derived from http://mustachified.com/master.js
// via http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2011-April/031243.html
// via https://bugs.webkit.org/show_bug.cgi?id=51652
// via http://code.google.com/p/chromium/issues/detail?id=67587

function dataURItoBlob(dataURI, callback) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs
    var byteString = atob(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    // write the ArrayBuffer to a blob, and you're done
    var bb = new window.WebKitBlobBuilder();
    bb.append(ab);
    return bb.getBlob(mimeString);
}

用法:

// Save image data
function onInitFs(fs){
    fs.root.getFile(fileName, {create:true}, function(fileEntry) {
        fileEntry.createWriter(function(fileWriter) {
            fileWriter.write(dataURItoBlob(myCanvas.toDataURL("image/png")));
        }, fileErrorHandler);
    }, fileErrorHandler);
}, fileErrorHandler);

【讨论】:

  • 你说得对,就是把base64数据转换成int8数组,我没试过,但我想我应该把它转换成字节数组,所以你的答案就是我寻找。
  • 克里斯,只是想说声谢谢!您的评论对我帮助很大!
  • WebKitBlobBuilder(或 BlobBuilder)现已弃用且不可用,您应该使用:var dataView = new DataView(ab);返回新的 Blob([dataView], {type:mimeString});从 ArrayBuffer 中获取 blob
猜你喜欢
  • 2010-12-02
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-31
相关资源
最近更新 更多