Je suis relativement nouveau à Java et je tente d'écrire une application Android simple. J'ai un fichier texte important avec environ 3500 lignes dans le dossier d'actifs de mes applications et j'ai besoin de le lire dans une chaîne. J'ai trouvé un bon exemple sur la façon de faire cela, mais j'ai une question sur la raison pour laquelle la matrice d'octet est initialisée à 1024. Je ne voudrais-je pas l'initialiser à la longueur de mon fichier texte? De plus, je ne voudrais pas utiliser char code>, pas octet code>? Voici le code: private void populateArray(){
AssetManager assetManager = getAssets();
InputStream inputStream = null;
Reader iStreamReader = null;
try {
inputStream = assetManager.open("List.txt");
iStreamReader = new InputStreamReader(inputStream, "UTF-8");
} catch (IOException e) {
Log.e("IOException populateArray", e.getMessage());
}
String String = readTextFile(iStreamReader);
// more code here
}
private String readTextFile(InputStreamReader inputStreamReader) {
StringBuilder sb = new StringBuilder();
char buf[] = new char[2048];
int read;
try {
do {
read = inputStreamReader.read(buf, 0, buf.length);
if (read>0) {
sb.append(buf, 0, read);
}
} while (read>=0);
} catch (IOException e) {
Log.e("IOException readTextFile", e.getMessage());
}
return sb.toString();
}
4 Réponses :
Cet exemple n'est pas bon du tout. Il est plein de mauvaises pratiques (cachées des exceptions, ne pas fermer des flux dans des blocs enfin, ne spécifie pas un encodage explicite, etc.). Il utilise un tampon long 1024 octets car il n'a pas de moyen de connaître la longueur du flux d'entrée. P>
lire le didacticiel Java Io pour apprendre à lire le texte d'un Fichier. P>
Exactement. Pensez à cela: Si vous effectuez la matrice d'octet aussi longtemps que la longueur du flux d'entrée, et si le fichier devait être dit de 4 Go, vous chargeriez tous les 4 Go de ce fichier en RAM, ralentissez votre ordinateur et susceptibles de causer un crash système. C'est pourquoi vous avez lu 1024 octets à la fois, afin de minimiser la quantité de mémoire utilisée par le tableau.
Vous lisez le fichier dans un tampon de 1024 octets. Ensuite, ces 1024 octets sont écrits à OutputStream. Ce processus répète jusqu'à ce que l'ensemble du fichier soit lu dans la sortie. Comme JB Nizet mentionné l'exemple est plein de mauvaises pratiques. P>
Pour lire à partir d'un fichier I Usanly Utilisez un scanner et un StringBuilder.
Scanner scan = new Scanner(new BufferedInputStream(new FileInputStream(filename)), "UTF-8");
StringBuilder sb = new StringBuilder();
while (scan.hasNextLine()) {
sb.append(scan.nextLine());
sb.append("\n");
}
scan.close
return sb.toString();
Cela transformer potentiellement \ r \ n en \ n, corrompant le contenu d'origine.
@JB NIZET Oui Vous avez raison. Savez-vous un meilleur moyen de mettre en œuvre cela?
Oui. Enveloppez le flux d'entrée à l'intérieur d'un INPUTStreamReader et spécifiez le CHARSET lorsque vous le faites. Démarrez une boucle qui se lit dans un tampon [] de charme (1024 ou 2048, par exemple) jusqu'à ce que -1 soit renvoyé. À chaque itération, ajoute ce qui a été lu dans le tampon de charme à un StringBuilder et renvoie le contenu du StringBuilder.
Donc, je devrais convertir mon INPUTREAM en un format UTF-8 Charstream à l'aide de la classe INPUTStreamReader? Ensuite, j'ai lu dans un stringbuilder, non? J'ai posté cette approche dans mon op. S'il vous plait, faite moi part de votre avis. Merci.
Vous devez utiliser UTF-8 si vous savez que votre flux contient des caractères UTF8. Personne sauf que vous sait où provient ce flux et quel codage est utilisé. Votre nouveau code Snippet n'est pas vraiment meilleur que l'original: vous ignorez les exceptions et vous ne fermez même pas votre lecteur. Il doit être fermé dans un bloc enfin.
@JB NIZET Vous avez raison pour l'UTF-8 et c'est vrai que le flux n'était pas fermé, mais Scanner ne jette pas d'exceptions que FilenotFoundException pourrait être lancée par FileInputStream. Devrais-je essayer d'attraper des exceptions autour de la même manière?
@Lynch: Désolé pour la confusion. Mon commentaire précédent était une réponse à Bitnuk3r.
@JB NIZET Merci, je vais les réparer.
Je ne voudrais-je pas l'initialiser à la longueur de mon fichier texte? En outre, je ne voudrais pas utiliser de caractère, pas d'octets? P> blockQuote>
Oui, et oui ... et comme d'autres réponses ont dit, vous avez choisi un exemple avec un certain nombre d'erreurs dedans. P>
Cependant, il existe un problème théorique qui fait les deux; C'est-à-dire de régler la longueur de la mémoire tampon à la longueur de fichier et em> à l'aide d'un tampon de caractères plutôt qu'à un tampon d'octet. Le problème est que la taille du fichier est mesurée en octets, mais la taille du tampon doit être mesurée en caractères. Ceci est normalement bien, mais il est théoriquement possible em> que vous aurez besoin de plus de caractères que la taille du fichier en octets; par exemple. Si le fichier d'entrée utilisait un jeu de caractères 6 bits et que 4 caractères emballés en 3 octets. p>
Je lis la section sur les flux de caractères sur le lien de Jbnizet, mais il semble que je ne puisse pas utiliser FordWriter pour lire mon intrigueTream, car Assetmanager.Open ("3500LinetextFile.txt") renvoie un bytestream, pas un charstream. Cela signifie-t-il que je ne peux pas utiliser de caractères?
Un filewriter est utilisé pour écrire du texte dans un fichier. Vous souhaitez lire des caractères d'un flux d'entrée. C'est ce qu'est l'entréeStreamReader.