2009-08-26 49 views
0

我正在開發一個項目(BrowserIO - 去browserio dot googlecode dot com,如果你想查看代碼並在其上工作,歡迎幫助!)根據他們的示例(https://developer.mozilla.org/en/Code_snippets/File_I%2F%2FO#Simple),使用Firefox的nsIFileInputStream與nsIConverterInputStream結合使用,但僅加載全部數據的一部分。該代碼是:使用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在file_io.js的data = str.value;行設置一個斷點。然後從列表中選擇一個文本文件,然後單擊「打開」按鈕。在Firebug中,在面板上爲str.value設置一個手錶。看看這個文件......它應該被截斷,除非它很短。

作爲參考,上面的代碼是trunk/scripts/file_io.js中openFile()函數的主體。

任何人有任何線索這是怎麼回事?

回答

2

參見nsIConverterInputStream;基本上,-1並不意味着「給我所有的一切」,而是「給我默認金額」,文檔聲稱是8192.

更一般地說,如果你想用盡輸入流的內容,必須循環,直到它爲空。任何流合同中的任何內容都不能保證通話所返回的數據量是流內容的全部;如果需要的話,它甚至可能會返回比它立即可用的更少的返回。

+0

是的,我弄明白了之後,我搞砸了一下。我現在遇到的另一個問題是,當我通過轉換器流傳遞內容時,我必須提前知道文件編碼類型。例如,我有兩個文件:一個使用UTF-8,另一個使用Latin-1(ISO-8859-1)。如果我指定編碼,它只適用於一種類型的文件。你知道有什麼方法直接從fstream對象/ nsIFileInputStream訪問數據嗎?現在瀏覽MDC文檔,找不到太多... –

+0

您的想法在下面工作,但您想要的值不是字符串;它確實是一個更合適的字節數組。獲取後者很容易,只需要使用nsIBinaryInputStream而不是nsIScriptableStream。但是請注意,引擎蓋下的nsIScriptableInputStream.read會返回一個char *;如果文件包含空字節呢? C++ - > JS代碼無法知道返回的char *的長度大於strlen的長度,因此如果文件包含空值,則會得到截斷的字符串。這裏可能並不重要,但是我的書中正在玩火,我會避免它。 –

0

我發現如何在不轉換的情況下讀取文件,以避免不知道文件編碼類型的問題。答案是使用nsIScriptableInputStreamnsIFileInputStream

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()); 
+0

來自文檔:「注意:即使流對應於本地文件,也不應該使用此方法(available())來確定流的總大小。此外,由於流可以使用大於2^32字節的數據,這種方法不能表達底層數據源的整個大小。「 https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIScriptableInputStream#available() – makdad