Write Data URIs to a File in Firefox Extension

I am developing a Firefox addon. I need to save a bunch of data URI data to disk. How do I approach this?

I looked at the fragments of the input / output file in MDN , but the fragments do not help me.

There are async and sync methods. I would like to use the async method, but how can I write a binary using the async method

Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");

// file is nsIFile
var file = FileUtils.getFile("Desk", ["test.png"]);

// You can also optionally pass a flags parameter here. It defaults to
// FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
var ostream = FileUtils.openSafeFileOutputStream(file);

//base64 image that needs to be saved 
image ="iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";

// How can I create an inputstream from the image data URI?
var inputstream = createInputstream(image);

// The last argument (the callback) is optional.
NetUtil.asyncCopy(inputstream , ostream, function(status) {
  if (!Components.isSuccessCode(status)) {
    // Handle error!
    return;
  }

  // Data has been written to the file.
});
+4
source share
1 answer

It looks like you would like to write not the data URI, but the binary data that it โ€œcontainsโ€, so I will answer that.

, URI ( , data:application/octet-stream;base64, ;)

// btoa("helloworld") as a placeholder ;)
var imageDataURI = "data:application/octet-stream;base64,aGVsbG93b3JsZA==";

1 - OS.File

OS.File , . , NetUtil , stat , ( , , , ).

( ), OS.File.writeAtomic .

Components.utils.import("resource://gre/modules/osfile.jsm");

var file = OS.Path.join(OS.Constants.Path.desktopDir, "test.png");

var str = imageDataURI.replace(/^.*?;base64,/, "");
// Decode to a byte string
str = atob(str);
// Decode to an Uint8Array, because OS.File.writeAtomic expects an ArrayBuffer(View).
var data = new Uint8Array(str.length);
for (var i = 0, e = str.length; i < e; ++i) {
  data[i] = str.charCodeAt(i);
}

// To support Firefox 24 and earlier, you'll need to provide a tmpPath. See MDN.
// There is in my opinion no need to support these, as they are end-of-life and
// contain known security issues. Let not encourage users. ;)
var promised = OS.File.writeAtomic(file, data);
promised.then(
  function() {
    // Success!
  },
  function(ex) {
    // Failed. Error information in ex
  }
);

2 - NetUtil

NetUtil , async, .

, NetUtil.asyncFetch URL-, , .asyncCopy.

Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");

// file is nsIFile
var file = FileUtils.getFile("Desk", ["test.png"]);

NetUtil.asyncFetch(imageDataURI, function(inputstream, status) {
  if (!inputstream || !Components.isSuccessCode(status)) {
    // Failed to read data URI.
    // Handle error!
    return;
  }

  // You can also optionally pass a flags parameter here. It defaults to
  // FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
  var ostream = FileUtils.openSafeFileOutputStream(file);

  // The last argument (the callback) is optional.
  NetUtil.asyncCopy(inputstream , ostream, function(status) {
    if (!Components.isSuccessCode(status)) {
      // Handle error!
      return;
    }

    // Data has been written to the file.
  });
});
+5

All Articles