将数据URI写入Firefox扩展中的文件 [英] Write a data URI to a file in a Firefox extension
问题描述
我浏览了 MDN上的文件I / O片段,但这些片段对我没有多大帮助。
有异步和同步方法。使用异步方法,但我怎样才能使用异步方法编写二进制文件
Components.utils.import(resource:// GRE /模块/ NetUtil.jsm);
Components.utils.import(resource://gre/modules/FileUtils.jsm);
//文件是nsIFile
var file = FileUtils.getFile(Desk,[test.png]);
//你也可以选择在这里传递一个flags参数。它默认为
// FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
var ostream = FileUtils.openSafeFileOutputStream(file);
//需要保存的base64映像
image =iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4 // 8w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg ==;
//如何从图像数据URI创建输入流?
var inputstream = createInputstream(image);
//最后一个参数(回调)是可选的。
NetUtil.asyncCopy(inputstream,ostream,function(status){
if(!Components.isSuccessCode(status)){
// Handle error!
return;
}
//数据已被写入文件
});
我想要写的不是数据URI,而是它包含的二进制数据,所以我会回答这个问题。首先,假设我们得到了一些实际的数据URI ,(如果没有,添加 data:application / octet-stream; base64,
不是太难);
<$ );
var imageDataURI =data:application / octet-stream; base64,aGVsbG93b3JsZA ==;
> // btoa(helloworld)作为占位符;
选项1 - 使用 OS.File
在构建路径(with一些常量帮助), 我们可以采取一个快捷方式,我们可以使用 I am developing a Firefox addon. I need to save a bunch of data URI images to the disk. How do I approach to this? I have browsed through the file I/O snippets on MDN, but the snippets don't help me much. There are async and sync methods.I would like to use async method but how can I write a binary file using async method
It sounds like you'd like to write not the data URI but the binary data it "contains", so I'll answer that. First, lets assume we got some actual data URI, (if not, adding
After constructing a path (with some constants help),
We can take a shortcut in that we can use
这篇关于将数据URI写入Firefox扩展中的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! OS.File
具有真正异步的优点。另一方面, NetUtil
主要是 异步,因为
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,/,);
//解码为字节字符串
str = atob(str);
//解码为Uint8Array,因为OS.File.writeAtomic需要一个ArrayBuffer(View)。
var data = new Uint8Array(str.length); (var i = 0,e = str.length; i< e; ++ i){
data [i] = str.charCodeAt(i);
}
//要支持Firefox 24及更早版本,您需要提供一个tmpPath。请参阅MDN。
//在我看来,没有必要支持这些,因为它们是报废的,
//包含已知的安全问题。我们不鼓励用户。 ;)
var promised = OS.File.writeAtomic(file,data);
promised.then(
function(){
//成功!
},
函数(ex){
//失败。 ex
}
);
选项2 - 使用
NetUtil
NetUtil
有一些缺点,就是不完全异步,如上所述。
NetUtil.asyncFetch
直接获取URL,这给了我们一个可以传递给< code .asyncCopy 。
Components.utils.import(resource:// GRE /模块/ NetUtil.jsm);
Components.utils.import(resource://gre/modules/FileUtils.jsm);
//文件是nsIFile
var file = FileUtils.getFile(Desk,[test.png]);
NetUtil.asyncFetch(imageDataURI,function(inputstream,status){
if(!inputstream ||!Components.isSuccessCode(status)){
//读取数据失败URI。
//处理错误!
return;
}
//你也可以选择传递一个flags参数,默认为
/ / FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE;
var ostream = FileUtils.openSafeFileOutputStream(file);
//最后一个参数(回调)是可选的。 b NetUtil.asyncCopy(inputstream,ostream,function(status){
if(!Components.isSuccessCode(status)){
//处理错误!
return;
}
//数据已被写入文件
});
});
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.
});
data:application/octet-stream;base64,
isn't too hard ;)// btoa("helloworld") as a placeholder ;)
var imageDataURI = "data:application/octet-stream;base64,aGVsbG93b3JsZA==";
Option 1 - Using
OS.File
OS.File
has the benefit that it is truly async. On the other hand, NetUtil
is only mostly async, in that there will be stat
calls on the main thread and the file will be opened and potentially closed on the main thread as well (which can lead to buffer flushes and hence block the main thread while the flush is happening).OS.File.writeAtomic
is suited for the job. 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's not encourage users. ;)
var promised = OS.File.writeAtomic(file, data);
promised.then(
function() {
// Success!
},
function(ex) {
// Failed. Error information in ex
}
);
Option 2 - Using
NetUtil
NetUtil
has some drawbacks in that is is not fully async, as already stated above.NetUtil.asyncFetch
to directly fetch the URL, which gives us a stream we can pass along to .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.
});
});