Javascript 使用nsIFileInputStream时加载的数据被截断&;NSI转换流

Javascript 使用nsIFileInputStream时加载的数据被截断&;NSI转换流,javascript,firefox,xpcom,Javascript,Firefox,Xpcom,我正在做一个项目(BrowserIO-如果你想查看代码并处理它,请访问BrowserIO.googlecode.com。欢迎光临!),在这个项目中,我使用Firefox的nsIFileInputStream和nsIConverterInputStream,根据他们的示例(),但只加载了一部分完整数据。代码是: var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interface

我正在做一个项目(BrowserIO-如果你想查看代码并处理它,请访问BrowserIO.googlecode.com。欢迎光临!),在这个项目中,我使用Firefox的nsIFileInputStream和nsIConverterInputStream,根据他们的示例(),但只加载了一部分完整数据。代码是:

var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(path);
var data = "";

var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
var cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"].createInstance(Components.interfaces.nsIConverterInputStream);

fstream.init(file, -1, 0, 0);
cstream.init(fstream, "UTF-8", 0, 0); // you can use another encoding here if you wish

var str = {};
cstream.readString(-1, str); // read the whole file and put it in str.value
data = str.value;

cstream.close(); // this closes fstream
如果您想查看此行为,请从BrowserIO项目页面签出代码,并使用Firebug在
data=str.value处设置断点文件_io.js中的行。然后从列表中选择一个文本文件,并单击“打开”按钮。在Firebug中,在“监视”面板中设置str.value的监视。看看文件。。。它应该被截断,除非它真的很短

作为参考,上面的代码是trunk/scripts/file_io.js中openFile()函数的主体

有人知道这是怎么回事吗;基本上,-1并不意味着“给我一切”,而是“给我默认金额”,文档声称是8192


更一般地说,如果您想要耗尽输入流的内容,您必须循环直到它为空。任何流协定中的任何内容都不能保证调用返回的数据量是流内容的全部;如果需要,它甚至可以返回比立即可用的更少的文件。

我发现了如何在不转换的情况下读取文件,以避免不知道文件编码类型的问题。答案是将
nsIScriptableInputStream
nsIFileInputStream
一起使用:

var sstream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
fstream.init(file, 0x01, 0004, 0);
sstream.init(fstream);
data = sstream.read(sstream.available());

是的,我把它弄得乱七八糟后才发现。我现在遇到的另一个问题是,当我通过转换器流传递内容时,我必须提前知道文件编码类型。例如,我有两个文件:一个是UTF-8,另一个是Latin-1(ISO-8859-1)。如果我指定了编码,它只对一种类型的文件起作用。您知道直接从fstream对象/nsIFileInputStream访问数据的方法吗?现在就浏览MDC文档,找不到太多内容……下面的想法很有效,但您想要的值不是字符串;它实际上更适合于字节数组。获取后者非常简单,只需要使用nsIBinaryInputStream而不是nsIScriptableStream。但是请注意,引擎盖下的nsIScriptableInputStream.read返回一个char*;如果文件包含空字节怎么办?C++->JS代码无法知道返回的char*的长度大于strlen所指示的长度,因此如果文件包含空值,则会得到截断的字符串。这在这里可能无关紧要,但在我的书中它是在玩火,我会避免它即使流对应于本地文件,也不应用于确定流的总大小。此外,由于流可能提供超过2^32字节的数据,此方法无法表示基础数据源的整个大小。”