从 javascript 写入二进制数据(Firefox 插件)

发布于 2025-01-06 11:47:55 字数 1801 浏览 0 评论 0原文

你好:我正在编写一个 Firefox 扩展(我的第一个扩展),除此之外,它还可以将图像 url 读入字节数组,然后将该二进制信息写入文件。我已经使用了这个示例,看起来好像可行,但该文件不正确,就好像对其执行了某种字符转换一样。

我的版本如下:

testWriteBinaryFile : function (dir, filename, data) {
    var aFile = Components.classes["@mozilla.org/file/local;1"].
        createInstance(Components.interfaces.nsILocalFile);

    aFile.initWithPath( "/home/mike/mypicture.gif" );
    aFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0600);
    Firebug.Console.log("Binary writing: file set up");

    var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"].
                 createInstance(Components.interfaces.nsIFileOutputStream);
    stream.init(aFile, 0x04 | 0x08 | 0x20, 0600, 0); // readwrite, create, truncate
    Firebug.Console.log("Binary writing: stream set up");

    Firebug.Console.log("Data length: " + data.length);
    Firebug.Console.log("Data byte 0: " + data[0].toString(16));
    Firebug.Console.log("Data byte 1: " + data[1].toString(16));
    Firebug.Console.log("Data byte 2: " + data[2].toString(16));
    Firebug.Console.log("Data byte 3: " + data[3].toString(16));
    Firebug.Console.log("Data byte 4: " + data[4].toString(16));

    stream.write(data, data.length);
    Firebug.Console.log("Binary writing: stream written")
    if (stream instanceof Components.interfaces.nsISafeOutputStream) {
        stream.finish();
    } else {
        stream.close();
    }
    Firebug.Console.log("Binary writing: done.");
}

通过打印出前几个字节,我知道数据缓冲区本身没问题,但文件在磁盘上后就完全不同了。有什么想法或任何其他方法来写出二进制文件吗?

我知道这是同步写入,但文件很小(20Kb)...但这是唯一的例子。如果我能解决这个问题,我的扩展就完成了!任何和所有的帮助表示赞赏。

Hi: I'm writing a firefox extension (my first) that among other things, gets an image url read into a byte Array, and then writes out that binary information to a file. I have used this example, which looks as if it works, but the file is not right, as if some sort of character conversion has been performed on it.

My version is as follows:

testWriteBinaryFile : function (dir, filename, data) {
    var aFile = Components.classes["@mozilla.org/file/local;1"].
        createInstance(Components.interfaces.nsILocalFile);

    aFile.initWithPath( "/home/mike/mypicture.gif" );
    aFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0600);
    Firebug.Console.log("Binary writing: file set up");

    var stream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"].
                 createInstance(Components.interfaces.nsIFileOutputStream);
    stream.init(aFile, 0x04 | 0x08 | 0x20, 0600, 0); // readwrite, create, truncate
    Firebug.Console.log("Binary writing: stream set up");

    Firebug.Console.log("Data length: " + data.length);
    Firebug.Console.log("Data byte 0: " + data[0].toString(16));
    Firebug.Console.log("Data byte 1: " + data[1].toString(16));
    Firebug.Console.log("Data byte 2: " + data[2].toString(16));
    Firebug.Console.log("Data byte 3: " + data[3].toString(16));
    Firebug.Console.log("Data byte 4: " + data[4].toString(16));

    stream.write(data, data.length);
    Firebug.Console.log("Binary writing: stream written")
    if (stream instanceof Components.interfaces.nsISafeOutputStream) {
        stream.finish();
    } else {
        stream.close();
    }
    Firebug.Console.log("Binary writing: done.");
}

I know the data buffer itself is OK by printing out the first few bytes, but the file is completely different once on disk. Any ideas or indeed any other ways to write out a binary file?

I know this is a synchronous write, but the files are small, (20Kb)... but that's the only example. If I can fix this I have the extension finished! Any and all help appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沉睡月亮 2025-01-13 11:47:55

这里的代码工作正常 - 例如,如果 data"foo\0\n\rbar" 该字符串被正确写入磁盘。也许问题是 nsIOutputStream.write() 需要一个字符串作为参数,但是您正在谈论一个字节数组。如果您的 data 变量确实是一个字节数组,那么首先将其转换为字符串可能是最简单的:

data = String.fromCharCode.apply(String, data);

在该操作之后,data 是与原始字节数组对应的字符串,并且可以与 nsIOutputStream.write() 一起使用。更有效(但在这种情况下可能不必要)的方法是使用 nsIBinaryOutputStream,类似这个:

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

var stream = FileUtils.openSafeFileOutputStream(aFile, FileUtils.MODE_WRONLY |
                                                       FileUtils.MODE_CREATE);

var binaryStream = Components.classes["@mozilla.org/binaryoutputstream;1"]
                             .createInstance(Components.interfaces.nsIBinaryOutputStream);
binaryStream.setOutputStream(stream);
binaryStream.writeByteArray(data, data.length);

FileUtils.closeSafeFileOutputStream(stream);

我正在使用 FileUtils 模块 在这个例子中,它使事情变得更简单。

The code as you have it here works fine - e.g. it if data is "foo\0\n\rbar" that string is correctly written to disk. Maybe the issue is that nsIOutputStream.write() expects a string as parameter, you are talking about a byte array however. If your data variable is indeed a byte array then maybe it is easiest to convert it into a string first:

data = String.fromCharCode.apply(String, data);

After that operation data is a string corresponding to the original byte array and can be used with nsIOutputStream.write(). The more efficient (but probably unnecessary in this case) approach would be using nsIBinaryOutputStream, something like this:

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

var stream = FileUtils.openSafeFileOutputStream(aFile, FileUtils.MODE_WRONLY |
                                                       FileUtils.MODE_CREATE);

var binaryStream = Components.classes["@mozilla.org/binaryoutputstream;1"]
                             .createInstance(Components.interfaces.nsIBinaryOutputStream);
binaryStream.setOutputStream(stream);
binaryStream.writeByteArray(data, data.length);

FileUtils.closeSafeFileOutputStream(stream);

I am using FileUtils module in this example, it makes things a lot simpler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文