0

在浪费了我两天的时间来找出这个脚本出了什么问题之后,最后我决定问它。

我想要做什么

我正在尝试从远程服务器读取文本文件。然后在加载我的 Firefox 扩展/插件时将所有文本文件更新存储到 SQLITE 数据库。

我试过的

var updatereader = {

    start: function () {
    //alert('reading update');
        var fURL = null;
        var ioService = null;
        var fURI = null;
        var httpChannel = null;

        fURL = "http://www.example.com/addon/mlist.txt";
        ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
        fURI = ioService.newURI(fURL, null, null);
        httpChannel = ioService.newChannelFromURI(fURI).QueryInterface(Components.interfaces.nsIHttpChannel);
        httpChannel.asyncOpen(updatereader.StreamReader, null);
    },

    onUpdateCompleted: function () {

    },

    StreamReader:
    {
        fOutputStream: null,
        fPointer: null,
        tempFile: "mlist.txt",

        onStartRequest: function (aRequest, aContext) {
        //alert('onStart');
            updatereader.StreamReader.fOutputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
            updatereader.StreamReader.fPointer = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
            updatereader.StreamReader.fPointer.append(updatereader.StreamReader.tempFile);
            updatereader.StreamReader.fOutputStream.init(updatereader.StreamReader.fPointer, 0x02 | 0x20 | 0x08, 0644, 0);
        },

        onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) {
        //control flow is not entering here - may be here is somehting missing
            var sStream = null;
            var tempBuffer = null;
            sStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
            sStream.init(aInputStream);
            tempBuffer = sStream.read(aCount);
            updatereader.StreamReader.fOutputStream.write(tempBuffer, aCount);
        },

        onStopRequest: function (aRequest, aContext, aStatusCode) {
        //alert('onStop');
            var currentDate = new Date();
            if (aStatusCode == 0) {
                fileInputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);

                updatereader.StreamReader.fOutputStream.close();
                fileInputStream.init(updatereader.StreamReader.fPointer, 0x01, 0, 0);
                lineInputStream = fileInputStream.QueryInterface(Components.interfaces.nsILineInputStream);

             //pass data to somewhere 
              var dbH = new dbstore();
              dbH.updateData(lineInputStream);

                lineInputStream.close();

                updatereader.StreamReader.fPointer.remove(false);


                updatereader.onUpdateCompleted();
            } else {

            }
        }
    }
}

问题:

什么都没有lineInputStream,将读取的数据传递到其他地方进行存储。

问题区域:

程序控制流程未进入本节

 onDataAvailable:

没有收到任何错误。

4

1 回答 1

0

首先,似乎真的不需要先将文件读入磁盘(除非它非常非常大)。

我只是XMLHttpRequest用来获取文件,当从特权上下文(例如附加代码,但不是网站)运行时,它可以访问任何有效的 URI。 XMLHttpRequest将简化几乎所有事情,例如不再需要 onDataAvailable,(通常)不再需要手动文本转换等。此外,在传输过程中无需敲击磁盘。

代码看起来像这样:

var req = new XMLHttpRequest();
req.open("GET", "http://www.example.com/addon/mlist.txt"); // file:/// would work too, BTW
req.overrideMimeType("text/plain");
req.addEventListener("load", function() {
  // Do something with req.responseText
}, false);
req.addEventListener("error", function() {
  // Handle error
}, false);
req.send();

如果你想XMLHttpRequest在非窗口中使用,例如js代码模块或js组件,那么你需要先初始化一个构造函数。这对窗口来说不是必需的,包括 XUL 窗口和 XUL 覆盖。

// Add XMLHttpRequest constructor, if not already present
if (!('XMLHttpRequest' in this)) {
    this.XMLHttpRequest = Components.Constructor("@mozilla.org/xmlextras/xmlhttprequest;1", "nsIXMLHttpRequest");
}

SDK 用户应使用该request模块,或者net/xhr如果需要较低级别的 API。

PS:如果您仍然对使用原始频道感兴趣,这里是我在 Scratchpad 中编写的一个最小示例(要运行,请为特权位置打开一个 Scratchpad,例如about:newtab)。您不应该从自己的实现中发出警报:alert()将旋转事件循环并导致可重入代码,这在此上下文中不受支持。

var {
    classes: Cc,
    interfaces: Ci,
    results: Cr,
    utils: Cu
} = Components;

Cu.import("resource://gre/modules/XPCOMUtils.jsm")
Cu.import("resource://gre/modules/Services.jsm");

var ConverterStream = Components.Constructor(
    "@mozilla.org/intl/converter-input-stream;1",
    "nsIConverterInputStream",
    "init");
var RC = Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;

function Listener() {
    this.content = "";
}
Listener.prototype = {
    QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener]),
    onStartRequest: function(req, ctx) {
        console.log("start");
    },
    onDataAvailable: function(req, ctx, stream, offset, count) {
        console.log("data", count);
        try {
            var cs = new ConverterStream(stream, null /* utf-8 */, 4096, RC);
            try {
                var str = {};
                while (cs.readString(4096, str)) {
                    this.content += str.value;
                }
            }
            finally {
                cs.close();
            }
        }
        catch (ex) {
            console.error("data", ex.message, ex);
        }
    },
    onStopRequest: function(req, ctx, status) {
        console.log("stop", status,
                    this.content.substr(0, 20), this.content.length);
    }
};

var uri = Services.io.newURI("http://example.org", null, null);
Services.io.newChannelFromURI(uri).asyncOpen(new Listener(), null);
于 2013-10-23T10:44:57.073 回答