javascript - 如何在 Firefox 扩展中使用 nsIArrayBufferInputStream 将 ArrayBuffer 直接异步写入文件

标签 javascript firefox asynchronous firefox-addon

长话短说: 如何在 Firefox 扩展中使用 nsIArrayBufferInputStream 将 ArrayBuffer 直接异步写入文件? MDN 似乎没有任何关于 nsIArrayBufferInputStream 的文档。

我知道我可以使用 nsIStringInputStream 并将 BufferArray 转换为 String,但这会对性能造成很大影响 还使用此代码将 ArrayBuffer 转换为字符串:

String.fromCharCode.apply(null, new Uint16Array(buf));

如果缓冲区为 500 KB 或更大,则不起作用,因此我们必须一次循环一个字符:

for (let i = 0; i < buf.length; i++){
    s += String.fromCharCode(buf16[i]);
}

或者,我可以使用 nsIBinaryOutputStream.writeByteArray 但它不能与 NetUtil.asyncCopy 一起使用(或者可以吗?)

//this works ok, but is synchronous :-(
function writeBinFile(aFile, data){
    Components.utils.import("resource://gre/modules/FileUtils.jsm");
    let nsFile = Components.Constructor("@mozilla.org/file/local;1", Ci.nsILocalFile, "initWithPath");
    if(typeof aFile === 'string') aFile = nsFile(aFile);
    var stream = FileUtils.openSafeFileOutputStream(aFile, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE);
    var binaryStream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
    binaryStream.setOutputStream(stream);
    binaryStream.writeByteArray(data, data.length);
    FileUtils.closeSafeFileOutputStream(stream);
}

说来话长……

我一直在尝试使用 nsIArrayBufferInputStream http://dxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIArrayBufferInputStream.idl 但没有成功。我试过的代码:

function fileWrite(file, data, callback) {
    Cu.import("resource://gre/modules/FileUtils.jsm");
    Cu.import("resource://gre/modules/NetUtil.jsm");
    let nsFile = Components.Constructor("@mozilla.org/file/local;1", Ci.nsILocalFile, "initWithPath");
    if (typeof file == 'string') file = new nsFile(file);
    let ostream = FileUtils.openSafeFileOutputStream(file)

    let istream = Cc["@mozilla.org/io/arraybuffer-input-stream;1"].createInstance(Ci.nsIArrayBufferInputStream);
    istream.setData(data, 0, data.length);

    let bstream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
    bstream.setInputStream(istream);

    //NetUtil.asyncCopy(istream, ostream,

    NetUtil.asyncCopy(bstream, ostream,
      function(status) {
          if (callback) callback(Components.isSuccessCode(status));
      }
    );
}

ArrayBuffer data 参数是来自 XMLHttpRequest 的响应:

function getBinFile(url, dir) {
  let nsFile = Components.Constructor("@mozilla.org/file/local;1", Ci.nsILocalFile, "initWithPath");
  let oReq = new XMLHttpRequest();
  oReq.open("GET", url, true);
  oReq.responseType = "arraybuffer";
  oReq.onload = function(oEvent) {
    var arrayBuffer = oReq.response;
    if (arrayBuffer) {
        //let byteArray = new Uint8Array(arrayBuffer);
        let byteArray = arrayBuffer;
        dir = /\\$/.test(dir) ? dir: dir + '\\';
        let file = nsFile(dir + decodeURIComponent(url.split('/').pop()));
        fileWrite(file, byteArray);
    }
  };
  oReq.send(null);
}

这样调用:

  getBinFile( 'http://....', 'c:\\demo\\');

文件已创建但没有内容!

最佳答案

我正在回答自己,以防有人偶然发现这个问题......

在 Josh Matthews(来自 Mozilla)的帮助下,我找到了答案: 使用 byteLength 而不是 length

istream.setData(data, 0, data.byteLength);

关于javascript - 如何在 Firefox 扩展中使用 nsIArrayBufferInputStream 将 ArrayBuffer 直接异步写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22486964/

相关文章:

javascript - 异步函数后未返回 React Native 元素

javascript - 如何获取没有 id 的 iframe 内 div 类中的文本?

html - Flexbox:Align-self:中心不适用于位置:已在 Firefox 中修复

python - Firefox 不恢复服务器发送的事件连接

html - 试图让一个 div w/100% 高度和溢出自动在 Firefox 中工作

python - Python 中的异步 HTTP 调用

javascript - 将参数 append 到当前 URL 上

javascript - SpookyJS 脚本完成后如何响应请求?

javascript - 在 if 语句中使用按位或运行函数

python - 如何重复请求任务