2017-04-07 3 views
0

Pourquoi ne puis-je pas lire la deuxième ligne sur l'utilisation de la deuxième instance de Scanner? J'obtiens un "java.util.NoSuchElementException: Aucune ligne trouvée".java.util.Scanner deuxième instance lancer NoSuchElementException

Je comprends que je devrais utiliser le hasNextLine() et évité l'exception, mais ma question est pourquoi la deuxième ligne ne serait pas disponible du tout? En outre, la raison pour laquelle il existe plusieurs instances de scanner est que, en réalité, le scanner est instancié dans une méthode appelée plusieurs fois, et je ne cherche pas de solution ou de solution.

Veuillez noter que je ne ferme ni les scanners ni les flux. Je ne lis que 1 ligne chacun en utilisant les scanners, alors que j'ai 3 lignes dans le flux.

Voici mon programme simplifié:

private void scanLines() { 
    String input = "Line 1." + System.lineSeparator() 
       + "Line 2." + System.lineSeparator() 
       + "Line 3." + System.lineSeparator(); 

    ByteArrayInputStream bais = new ByteArrayInputStream(input.getBytes()); 

    Scanner scanner1 = new Scanner(bais); 
    System.out.println(scanner1.nextLine()); 

    Scanner scanner2 = new Scanner(bais); 
    System.out.println(scanner2.nextLine()); 
} 

sortie est:

Line 1. 
Exception in thread "main" java.util.NoSuchElementException: No line found 
     at java.util.Scanner.nextLine(Unknown Source) 
     at ScannerTest.scanLines(ScannerTest.java:23) 
     at ScannerTest.main(ScannerTest.java:6) 
+2

N'utilisez jamais deux scanners sur le même flux – freedev

+1

Et pourquoi utilisez-vous un ByteArrayInputStream lorsque vous voulez lire des lignes de caractères ?! – GhostCat

+0

Il suffit d'utiliser le même scanner – Hackerman

Répondre

0

Utilisez plusieurs scanners (sur un même flux) est une très mauvaise pratique, car les scanners consomment le flux qu'ils partagent.

Ceci était la cause de l'exception java.util.NoSuchElementException: No line found que vous aviez.

J'ai testé votre code et l'exception est déclenchée par la seconde invocation nextLine().

Dans chaque classe Scanner est enregistrée une référence au même flux d'entrée.

Lorsque la méthode scanner1.nextLine() est invoquée, un ensemble d'octets est lu sur le flux et la position est avancée. Pour être clair, j'ai vérifié le débogage du code source de la classe Scanner.

Lorsque la méthode nextLine() est appelée, dans les coulisses du flux est déplacé avant 1024 la position de copier le résultat dans un tampon

// Internal buffer used to hold input 
private CharBuffer buf; 

Essayez de déboguer le code source Java vous et regardez la méthode readInput().

+0

Merci! une documentation/javadocs à ce sujet? – Jay

+0

Oui, la position du flux est avancée, mais elle doit être avancée d'une ligne et ne pas consommer le flux entier. – Jay

+0

Vous avez oublié qu'il y a un tampon sous-jacent ... peut-être que je me trompe ... – freedev