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

Javascript 如何在Firefox扩展中使用nsIArrayBufferInputStream将ArrayBuffer直接异步写入文件,javascript,firefox,asynchronous,firefox-addon,Javascript,Firefox,Asynchronous,Firefox Addon,长话短说: 如何在Firefox扩展中使用nsIArrayBufferInputStream将ArrayBuffer直接异步写入文件? MDN似乎没有关于nsIArrayBufferInputStream的任何文档 我知道我可以使用nsIStringInputStream并将BufferArray转换为字符串,但这会对性能造成很大影响 还可以使用以下代码将ArrayBuffer转换为字符串: String.fromCharCode.apply(null, new Uint16Array(buf)

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

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

String.fromCharCode.apply(null, new Uint16Array(buf));
如果缓冲区为500 KB或更大,则不起作用,因此我们必须一次循环一个字符:

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

我一直在尝试使用nsArrayBufferInputStream 但是没有成功。我尝试的代码:

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
param是来自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的)的帮助下,我找到了答案: 使用
bytellength
代替
length

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

您现在可以使用
OS.File.writeAtomic
,而不是所有这些,这要简单得多。请看这里:你好,MJSaedy我想我遇到了与您相同的问题,我试图将数据发布到loadOneTab,但当数据超过某个大小时失败,请检查此主题-
istream.setData(data, 0, data.byteLength);