本文介绍了将数据URI写入Firefox扩展中的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我正在开发一个Firefox插件。我需要将一堆数据URI映像保存到磁盘。我如何解决这个问题? 我浏览了 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 OS.File 具有真正异步的优点。另一方面, NetUtil 主要是 异步,因为 stat 调用主线程和文件将被打开,并可能关闭主线程(这可能会导致缓冲区刷新,从而阻止主线程,同时发生刷新)。 在构建路径(with一些常量帮助), 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,这给了我们一个可以传递给。 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; } //数据已被写入文件}); }); 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 Components.utils.import("resource://gre/modules/NetUtil.jsm");Components.utils.import("resource://gre/modules/FileUtils.jsm");// file is nsIFilevar 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.}); 解决方案 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 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.FileOS.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).After constructing a path (with some constants help), 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 stringstr = 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 NetUtilNetUtil has some drawbacks in that is is not fully async, as already stated above.We can take a shortcut in that we can use 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 nsIFilevar 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. });}); 这篇关于将数据URI写入Firefox扩展中的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
11-01 04:56