使用Firefox扩展程序从网站保存文本,保存错误的字符

时间:2013-12-10 18:15:15

标签: javascript firefox unicode firefox-addon firefox-addon-sdk

对于模糊的标题感到抱歉,但我有点迷失,所以很难具体。我开始使用附加SDK来玩Firefox扩展。我想要的是观看更改页面,在这种情况下是一个Twitch.tv聊天窗口,并将这些更改保存到文件中。

我已经开始工作了,每当页面上的某些内容发生变化时,它就会被保存。但是,“不寻常”的字符,例如韩语中的某些字符,并没有得到妥善保存。我认为这与文件/字符串的编码有关?我试着通过将它们复制粘贴到记事本中来保存相同的字符,它要求我保存为Unicode,当我做的时候一切正常。所以我想,好吧,我会在写入之前将日志文件的编码更改为unicode。没有完全正常工作......现在所有的角色都是某种外语。

我用来写文件的代码是:

    var {Cc, Ci, Cu} = require("chrome");
    var {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");
    var file = FileUtils.getFile("Desk", ["mylogfile.txt"]);
    var stream = FileUtils.openFileOutputStream(file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_APPEND);
    stream.write(data, data.length);
    stream.close();

我在MDN上查看了FileUtils.jsm的描述,据我所知,没有办法告诉它我想使用哪种编码?

如果你不知道修复可以给我一些好的搜索条件,因为我似乎在这方面做得很短。因为我基本上对这个问题一无所知,所以我现在正在黑暗中徘徊。

编辑: 这就是我(现在)最终得到的结果:

var {Cc, Ci, Cu} = require("chrome");
var {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm");

var file = Cc['@mozilla.org/file/local;1']
           .createInstance(Ci.nsILocalFile);

file.initWithPath('C:\\temp\\temp.txt');
if(!file.exists()){
  file.create(file.NORMAL_FILE_TYPE, 0666);
}

var charset = 'UTF-8';
var fileStream = Cc['@mozilla.org/network/file-output-stream;1']
.createInstance(Ci.nsIFileOutputStream);
fileStream.init(file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_APPEND, 0x200, false);

var converterStream = Cc['@mozilla.org/intl/converter-output-stream;1']
.createInstance(Ci.nsIConverterOutputStream);

converterStream.init(fileStream, charset, data.length,
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
converterStream.writeString(data);
converterStream.close();
fileStream.close();

1 个答案:

答案 0 :(得分:1)

仅转储原始字节(实际上是原始jschars)将无效。您需要先将数据转换为合理的编码。

参见例如File I/O Snippets。以下是创建转换器输出流包装器的关键部分:

var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].
                createInstance(Components.interfaces.nsIConverterOutputStream);
converter.init(foStream, "UTF-8", 0, 0);
converter.writeString(data);
converter.close(); // this closes foStream

另一种方法是使用OS.File + TextConverter

let encoder = new TextEncoder();                                   // This encoder can be reused for several writes
let array = encoder.encode("This is some text");                   // Convert the text to an array
let promise = OS.File.writeAtomic("file.txt", array,               // Write the array atomically to "file.txt", using as temporary
    {tmpPath: "file.txt.tmp"});                                    // buffer "file.txt.tmp".

甚至可以将两者混合使用。 OS.File的好处是它可以从主线程写入数据和访问文件(因此在写入文件时不会阻止UI)。