2010-10-04 3 views
6

L'une des lignes d'un fichier java que j'essaie de comprendre est la suivante.Lecture d'un fichier à l'aide d'un scanner Java

return new Scanner(file).useDelimiter("\\Z").next(); 

Le fichier devrait revenir jusqu'à « La fin de l'entrée, mais pour la terminaison finale, le cas échéant » selon la documentation java.util.regex.Pattern. Mais ce qui se passe est qu'il renvoie seulement les 1024 premiers caractères du fichier. Est-ce une limitation imposée par regex Pattern Matcher? Cela peut-il être surmonté? Actuellement, je vais de l'avant en utilisant un filereader. Mais j'aimerais connaître la raison de ce comportement.

+0

NE JAMAIS utiliser le scanner! Vraiment, vous aurez tellement de problèmes. –

+8

@Martijn Courteaux - attention à fournir le moindre indice quant à pourquoi Scanner est mauvais? – whaley

Répondre

2

Essayez d'envelopper l'objet dans un fileFileInputStream

+0

Pourriez-vous [modifier] votre réponse pour expliquer pourquoi cela pourrait aider, et quel est le problème sous-jacent? À l'heure actuelle, c'est un peu plus qu'un commentaire. –

5

Moi, je ne pouvais pas reproduire ça. Mais je pense que je peux faire la lumière sur ce qui se passe.

En interne, le scanner utilise un tampon de caractères de 1024 caractères. Par défaut, le scanner lira à partir de vos caractères lisible 1024, si possible, puis appliquera le motif.

Le problème est dans votre motif ... il correspondra toujours à la fin de l'entrée, mais cela ne signifie pas la fin de votre flux/données d'entrée. Lorsque Java applique votre modèle aux données mises en mémoire tampon, il essaie de trouver la première occurrence de la fin de l'entrée. Étant donné que 1024 caractères sont dans le tampon, le moteur correspondant appelle la position 1024 la première correspondance du délimiteur et tout ce qu'il contient avant d'être renvoyé comme premier jeton.

Je ne pense pas que l'ancre de fin d'entrée soit valide pour une utilisation dans le scanner pour cette raison. Cela pourrait être la lecture d'un flux infini, après tout.

+0

Salut Mark, je pense que c'est une bonne raison pour que le scanner ne fonctionne pas. Je vote la réponse. Le moyen de le faire fonctionner est celui marqué correct. Merci pour votre réponse. – Sharmila

1

Scanner est destiné à lire des primitives multiples à partir d'un fichier. Ce n'est vraiment pas destiné à lire un fichier entier.

Si vous ne souhaitez pas inclure les bibliothèques de tiers, vous êtes mieux en boucle sur une BufferedReader qui enveloppe un FileReader/InputStreamReader pour le texte, ou en boucle sur une FileInputStream pour les données binaires.

Si vous êtes OK avec une bibliothèque tiers, Apache commons-io a une classe FileUtils qui contient les méthodes statiques readFileToString et readLines pour le texte et readFileToByteArray pour les données binaires ..

0

Vous pouvez utiliser la classe Scanner, il suffit de spécifier un jeu de caractères lors de l'ouverture du scanner, à savoir:

Scanner sc = new Scanner(file, "ISO-8859-1"); 

Java convertit octets lus à partir du fichier en caractères à l'aide du jeu de caractères spécifié, qui est celui par défaut (du système d'exploitation sous-jacent) si rien n'est donné (source). Il n'est toujours pas clair pour moi pourquoi Scanner ne lit que 1024 octets avec celui par défaut, alors qu'avec un autre il atteint la fin d'un fichier. En tout cas, ça marche bien!