2009-08-26 5 views
0

Je travaille sur un projet (BrowserIO - allez sur browserio dot googlecode dot com si vous voulez vérifier le code et travailler dessus. en utilisant nsIFileInputStream de Firefox en tandem avec nsIConverterInputStream, selon leur exemple (https://developer.mozilla.org/en/Code_snippets/File_I%2F%2FO#Simple), mais seulement une partie des données complètes est en cours de chargement. Le code est:Les données chargées sont tronquées lors de l'utilisation de 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 

Si vous voulez voir ce comportement, checkout le code de la page du projet BrowserIO et utiliser Firebug pour définir un point d'arrêt à la ligne data = str.value; dans file_io.js. Ensuite, sélectionnez un fichier texte dans la liste et cliquez sur le bouton "Ouvrir". Dans Firebug, dans le panneau de la montre définir une montre pour str.value. Regardez le fichier ... Il devrait être tronqué, à moins que ce soit vraiment court. Pour référence, le code ci-dessus est le corps principal de la fonction openFile() dans trunk/scripts/file_io.js.

Quelqu'un a la moindre idée de ce qui se passe avec ça?

Répondre

2

Voir nsIConverterInputStream; fondamentalement, -1 ne veut pas dire «donnez-moi tout» mais plutôt «donnez-moi le montant par défaut», que les documents prétendent être 8192.

Plus généralement, si vous voulez épuiser le contenu d'un flux d'entrée, vous avoir à boucler jusqu'à ce qu'il soit vide. Rien dans les contrats de flux ne garantit que la quantité de données renvoyée par un appel est l'intégralité du contenu du flux; il pourrait même revenir moins qu'il n'a immédiatement disponible s'il le voulait.

+0

Ouais, je pensais que après que je foiré avec elle un peu. L'autre problème que j'ai maintenant est que quand je passe le contenu par le biais d'un flux de conversion, je dois connaître le type d'encodage du fichier à l'avance. Ainsi, par exemple, j'ai deux fichiers: un en UTF-8 et l'autre en Latin-1 (ISO-8859-1). Si je spécifie l'encodage, cela ne fonctionne que sur un type de fichier. Connaissez-vous un moyen d'accéder directement aux données à partir de l'objet fstream/nsIFileInputStream? Naviguez sur les documents MDC en ce moment, ne pas trouver beaucoup ... –

+0

Votre idée ci-dessous fonctionne, mais la valeur que vous voulez n'est pas une chaîne; c'est vraiment plus approprié un tableau d'octets. Obtenir ce dernier est assez facile et nécessite simplement d'utiliser nsIBinaryInputStream au lieu de nsIScriptableStream. Notez, cependant, que nsIScriptableInputStream.read sous le capot renvoie un char *; Que faire si le fichier contient des octets nuls? Le code C++ -> JS n'a aucun moyen de savoir que le caractère char * retourné a une longueur supérieure à celle que strlen indiquerait, donc vous obtiendrez des chaînes tronquées si votre fichier contient des valeurs nulles. Cela n'a peut-être pas d'importance ici, mais c'est jouer avec le feu dans mon livre, et je l'éviterais. –

0

J'ai découvert comment lire le fichier sans le convertir, pour éviter les problèmes de ne pas connaître le type de codage du fichier. La réponse est d'utiliser nsIScriptableInputStream avec 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()); 
+0

De la documentation: "Note: Cette méthode (available()) ne doit pas être utilisée pour déterminer la taille totale d'un flux, même si le flux correspond à un fichier local. 32 octets de données, cette méthode est incapable d'exprimer la taille entière de la source de données sous-jacente. " https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIScriptableInputStream#available() – makdad

Questions connexes