Scanner contre BufferedReader


284

Pour autant que je sache, les deux méthodes les plus courantes de lecture de données basées sur des caractères à partir d'un fichier en Java utilisent Scannerou BufferedReader. Je sais également que le BufferedReaderlit les fichiers efficacement en utilisant un tampon pour éviter les opérations sur le disque physique.

Mes questions sont:

  • Fonctionne Scanneraussi bien que BufferedReader?
  • Pourquoi choisiriez-vous Scannerplutôt BufferedReaderou vice versa?

1
J'utilise également généralement le scanner pour lire à partir de la norme dans («Scanner dans = nouveau scanner (System.in)» se sent beaucoup plus propre). Je ne sais pas si c'est réellement moins efficace, mais comme la lecture à partir de std est bloquante, je ne peux pas imaginer que l'efficacité du scanner soit le problème.
dimo414

Réponses:


201

Scannerest utilisé pour analyser les jetons du contenu du flux alors BufferedReaderqu'il lit simplement le flux et n'effectue aucune analyse spéciale.

En fait, vous pouvez passer de a BufferedReaderà a scannercomme source de caractères à analyser.


55
BufferedReader est synchronisé et Scanner ne l'est pas, donc c'est à vous de décider.
Ruben

1
Je sais que ce sujet est ancien, mais j'ai eu des résultats mitigés parmi les systèmes d'exploitation utilisant BufferedReader lorsque j'essayais de récupérer du contenu à partir des flux fournis par Process (c'est-à-dire capturer la sortie d'une commande externe). Une fois que j'ai changé mon code pour utiliser plutôt Scanner, comme indiqué dans une réponse séparée , les choses ont commencé à se comporter de manière cohérente et comme prévu.
ewh

@Reuben Mais Scannerdépend en fin de compte d'autre chose pour son entrée, qui pourrait bien être synchronisée.
Marquis de Lorne

189

Dans la dernière version / build JDK6 (b27), le Scannera un tampon plus petit ( 1024 caractères ) par opposition au BufferedReader( 8192 caractères ), mais c'est plus que suffisant.

Quant au choix, utilisez le Scannersi vous voulez analyser le fichier, utilisez le BufferedReadersi vous voulez lire le fichier ligne par ligne. Voir également le texte d'introduction de leurs documentations API précitées.

  • Analyse = interpréter l'entrée donnée comme des jetons (parties). Il est capable de vous redonner des parties spécifiques directement comme int, chaîne, décimal, etc. Voir aussi toutes ces nextXxx()méthodes en Scannerclasse.
  • Lecture = streaming stupide. Il vous redonne toujours tous les personnages, que vous devez à votre tour inspecter manuellement si vous souhaitez faire correspondre ou composer quelque chose d'utile. Mais si vous n'avez pas besoin de le faire de toute façon, la lecture suffit.

1
Joli. Merci pour la pointe du tampon. Le cherchait depuis le début car les lectures natives sont extrêmement coûteuses.
Achow

7
@Asif: parsing = interpréter l'entrée donnée comme des jetons (parties). Il est capable de vous redonner des parties spécifiques directement comme int, chaîne, décimale, etc. Voir aussi toutes ces méthodes nextXxx () dans la classe Scanner. Lecture = streaming stupide. Il vous redonne toujours tous les personnages, que vous devez à votre tour inspecter manuellement si vous souhaitez faire correspondre ou composer quelque chose d'utile. Mais si vous n'avez pas besoin de le faire de toute façon, la lecture suffit.
BalusC

@BalusC Ok j'ai déjà utilisé, readInt();readFloat (); etc. Maintenant, quel est le moyen d'analyser. et BalusC pouvez-vous me donner peu de temps à seulement 10 minutes dans la salle de chat, je veux en savoir peu sur la mise en mémoire tampon, comment cela fonctionne.
Asif Mushtaq

Qu'est-ce que j'enveloppe BufferedReaderdans le constructeur de Scanner? Est-ce une bonne idée?
vivek

1
ScannerLe tampon sera étendu au besoin pour la correspondance de motifs. Donc, si vous voulez un tampon plus grand, il vous suffit de l'invoquer, par exemple findWithinHorizon("\\z", 8192), et ensuite, il utilisera un tampon avec une capacité de 8192caractères (ou le fichier entier s'il est plus petit que cela).
Holger

77

Voir ce lien , ce qui suit est cité à partir de là:

Un BufferedReader est une classe simple destinée à lire efficacement à partir du flux sous-jacent. Généralement, chaque demande de lecture faite d'un Reader comme un FileReader provoque une demande de lecture correspondante à effectuer au flux sous-jacent. Chaque appel de read () ou readLine () peut entraîner la lecture d'octets dans le fichier, leur conversion en caractères, puis leur renvoi, ce qui peut être très inefficace. L'efficacité est sensiblement améliorée si un Reader est déformé dans un BufferedReader.

BufferedReader est synchronisé, donc les opérations de lecture sur un BufferedReader peuvent être effectuées en toute sécurité à partir de plusieurs threads.

Un scanner, d'autre part, contient beaucoup plus de fromage; il peut faire tout ce qu'un BufferedReader peut faire et au même niveau d'efficacité. Cependant, en plus, un scanner peut analyser le flux sous-jacent pour les types et chaînes primitifs à l'aide d'expressions régulières. Il peut également symboliser le flux sous-jacent avec le délimiteur de votre choix. Il peut également effectuer un balayage direct du flux sous-jacent sans tenir compte du délimiteur!

Un scanner n'est cependant pas sûr pour les threads, il doit être synchronisé en externe.

Le choix d'utiliser un BufferedReader ou un Scanner dépend du code que vous écrivez, si vous écrivez un simple lecteur de journaux Le lecteur tamponné est adéquat. Cependant, si vous écrivez un analyseur XML, c'est le choix le plus naturel.

Même en lisant l'entrée, si vous voulez accepter l'entrée utilisateur ligne par ligne et dire simplement l'ajouter à un fichier, un BufferedReader est assez bon. D'un autre côté, si vous souhaitez accepter une entrée utilisateur en tant que commande avec plusieurs options, et que vous souhaitez ensuite effectuer différentes opérations en fonction de la commande et des options spécifiées, un scanner conviendra mieux.


"Un scanner, d'autre part, contient beaucoup plus de fromage; il peut faire tout ce qu'un BufferedReader peut faire et au même niveau d'efficacité." Ne soyez pas d'accord, BufferedReader est un peu plus rapide que Scanner car Scanner analyse les données d'entrée et BufferedReader lit simplement la séquence de caractères.
Pratik

40
  1. BufferedReadera une mémoire tampon beaucoup plus grande que Scanner. À utiliser BufferedReadersi vous souhaitez obtenir de longues chaînes à partir d'un flux et à utiliser Scannersi vous souhaitez analyser un type spécifique de jeton à partir d'un flux.

  2. Scannerpeut utiliser tokenize à l'aide d'un délimiteur personnalisé et analyser le flux en types de données primitifs, tandis BufferedReaderqu'il ne peut lire et stocker que String.

  3. BufferedReaderest synchrone alors qu'il Scannerne l'est pas. À utiliser BufferedReadersi vous travaillez avec plusieurs threads.

  4. Scannermasque IOException tout en le BufferedReaderlançant immédiatement.


18

Je suggère d'utiliser BufferedReaderpour lire du texte. Scannerse cache IOExceptiontout en le BufferedReaderjetant immédiatement.


12

Les différences entre BufferedReader et Scanner sont les suivantes:

  1. BufferedReader est synchronisé mais le scanner n'est pas synchronisé .
  2. BufferedReader est thread-safe mais Scanner n'est pas thread-safe .
  3. BufferedReader a une mémoire tampon plus grande mais Scanner a une mémoire tampon plus petite .
  4. BufferedReader est plus rapide mais le Scanner est plus lent à exécuter .
  5. Code pour lire une ligne depuis la console:

    BufferedReader :

     InputStreamReader isr=new InputStreamReader(System.in);
     BufferedReader br= new BufferedReader(isr);
     String st= br.readLine();

    Scanner :

    Scanner sc= new Scanner(System.in);
    String st= sc.nextLine();

8

Voici les différences entre BufferedReader et Scanner

  1. BufferedReader ne lit que les données mais le scanner analyse également les données.
  2. vous pouvez uniquement lire String en utilisant BufferedReader, mais vous pouvez lire int, long ou float en utilisant Scanner.
  3. BufferedReader est plus ancien que Scanner, il existe depuis jdk 1.1 tandis que Scanner a été ajouté sur la version JDK 5.
  4. La taille du tampon de BufferedReader est grande (8 Ko) par rapport à 1 Ko du scanner.
  5. BufferedReader est plus approprié pour lire un fichier avec une chaîne longue tandis que Scanner est plus approprié pour lire une petite entrée utilisateur à partir d'une invite de commande.
  6. BufferedReader est synchronisé mais pas Scanner, ce qui signifie que vous ne pouvez pas partager Scanner entre plusieurs threads.
  7. BufferedReader est plus rapide que Scanner car il ne passe pas de temps à analyser
  8. BufferedReader est un peu plus rapide que le scanner
  9. BufferedReader est du package java.io et Scanner est du package java.util sur la base des points que nous pouvons sélectionner notre choix.

Merci


6

Les principales différences:

  1. Scanner

  • Un simple scanner de texte qui peut analyser les types et les chaînes primitifs à l'aide d'expressions régulières.
  • Un scanner divise son entrée en jetons à l'aide d'un modèle de délimiteur, qui correspond par défaut aux espaces blancs. Les jetons résultants peuvent ensuite être convertis en valeurs de différents types en utilisant les différentes méthodes suivantes.

Exemple

 String input = "1 fish 2 fish red fish blue fish";
 Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
 System.out.println(s.nextInt());
 System.out.println(s.nextInt());
 System.out.println(s.next());
 System.out.println(s.next());
 s.close(); 

imprime la sortie suivante:

 1
 2
 red
 blue 

La même sortie peut être générée avec ce code, qui utilise une expression régulière pour analyser les quatre jetons à la fois:

 String input = "1 fish 2 fish red fish blue fish";

 Scanner s = new Scanner(input);
 s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
 MatchResult result = s.match();
 for (int i=1; i<=result.groupCount(); i++)
     System.out.println(result.group(i));
 s.close(); `


  1. BufferedReader:

    • Lit le texte à partir d'un flux d'entrée de caractères, en mettant les caractères en mémoire tampon afin de permettre une lecture efficace des caractères, des tableaux et des lignes.

    • La taille du tampon peut être spécifiée ou la taille par défaut peut être utilisée. La valeur par défaut est suffisamment grande pour la plupart des applications.

En général, chaque demande de lecture faite à partir d'un lecteur entraîne une demande de lecture correspondante à partir du flux de caractères ou d'octets sous-jacent. Il est donc conseillé d'enrouler un BufferedReader autour de tout lecteur dont les opérations read () peuvent être coûteuses, telles que FileReaders et InputStreamReaders. Par exemple,

BufferedReader in
   = new BufferedReader(new FileReader("foo.in"));

mettra en mémoire tampon l'entrée du fichier spécifié. Sans mise en mémoire tampon, chaque invocation de read () ou readLine () peut entraîner la lecture d'octets dans le fichier, leur conversion en caractères, puis leur renvoi, ce qui peut être très inefficace. Les programmes qui utilisent DataInputStreams pour la saisie textuelle peuvent être localisés en remplaçant chaque DataInputStream par un BufferedReader approprié.

Source: Lien


3

Il existe différentes façons de saisir des données en java comme:

1) BufferedReader 2) Scanner 3) Arguments de ligne de commande

BufferedReader Lire du texte à partir d'un flux d'entrée de caractères, en tamponnant les caractères de manière à permettre une lecture efficace des caractères, des tableaux et des lignes.

Où Scanner est un simple scanner de texte qui peut analyser des types et des chaînes primitifs à l'aide d'expressions régulières.

si vous écrivez un simple lecteur de journaux Le lecteur tamponné est adéquat. si vous écrivez un analyseur XML, c'est le choix le plus naturel.

Pour plus d'informations, veuillez consulter:

http://java.meritcampus.com/t/240/Bufferedreader?tc=mm69


1

La réponse ci-dessous est tirée de la lecture à partir de la console: JAVA Scanner vs BufferedReader

Lors de la lecture d'une entrée depuis la console, il existe deux options pour y parvenir. Première utilisation Scanner, une autre utilisation BufferedReader. Les deux ont des caractéristiques différentes. Cela signifie des différences sur la façon de l'utiliser.

Le scanner a traité l'entrée donnée comme un jeton. BufferedReader vient de lire ligne par ligne l'entrée donnée sous forme de chaîne. Le scanner lui-même fournit des capacités d'analyse tout comme nextInt (), nextFloat ().

Mais, quelles sont les autres différences entre?

  • Le scanner a traité l'entrée donnée comme un jeton. BufferedReader en tant que ligne de flux / chaîne
  • Scanner tokenized entrée donnée en utilisant regex. L'utilisation de BufferedReader doit écrire du code supplémentaire
  • BufferedReader plus rapide que Scanner * point no. 2
  • Le scanner n'est pas synchronisé, BufferedReader synchronisé

Le scanner est fourni depuis la version 1.5 du JDK.

Quand utiliser un scanner ou un lecteur tamponné?

Regardez les principales différences entre les deux, l'une utilisant des jetons, d'autres utilisant la ligne de flux. Lorsque vous avez besoin de capacités d'analyse, utilisez plutôt Scanner. Mais je suis plus à l'aise avec BufferedReader. Lorsque vous devez lire à partir d'un fichier, utilisez BufferedReader, car il s'agit d'utiliser un tampon lors de la lecture d'un fichier. Ou vous pouvez utiliser BufferedReader comme entrée pour le scanner.


0
  1. BufferedReader vous donnera probablement de meilleures performances (car le scanner est basé sur InputStreamReader, regardez les sources). ups, pour la lecture de fichiers, il utilise nio. Lorsque j'ai testé les performances de nio par rapport aux performances de BufferedReader pour les gros fichiers, nio affiche des performances un peu meilleures.
  2. Pour lire à partir d'un fichier, essayez Apache Commons IO.

0

Je préfère, Scannercar il ne lève pas d'exceptions vérifiées et, par conséquent, son utilisation entraîne un code plus rationalisé.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.