web-dev-qa-db-fra.com

Différence spécifique entre bufferedreader et filereader

J'aimerais connaître la différence spécifique entre BufferedReader et FileReader

Je sais que BufferedReader est beaucoup plus efficace que FileReader, mais quelqu'un peut-il expliquer pourquoi (de manière spécifique et détaillée)? Merci.

43
Outlier

De manière simple:

Une classe FileReader est un outil général permettant de lire des caractères à partir d'un fichier. La classe BufferedReader peut englober des lecteurs, tels que FileReader, pour mettre en tampon l'entrée et améliorer l'efficacité. Vous ne pouvez donc pas utiliser l'un sur l'autre, mais les deux en même temps en transmettant l'objet FileReader au constructeur BufferedReader. 

Très détail

FileReader est utilisé pour l'entrée de données de caractères à partir d'un fichier de disque. Le fichier d'entrée peut être un fichier ASCII ordinaire, un octet par fichier texte. Un flux Reader traduit automatiquement les caractères du format de fichier du disque en format de caractère interne. Les caractères du fichier d'entrée peuvent provenir d'autres alphabets pris en charge par le format UTF, auquel cas il y aura jusqu'à trois octets par caractère. Dans ce cas également, les caractères du fichier sont traduits au format char.

enter image description here

Comme pour la sortie, il est recommandé d’utiliser un tampon pour améliorer l’efficacité. Utilisez BufferedReader pour cela. C'est la même classe que nous avons utilisée pour la saisie au clavier. Ces lignes doivent avoir l’air familier:

BufferedReader stdin =
    new BufferedReader(new InputStreamReader( System.in ));

Ces lignes créent un BufferedReader, mais connectez-le à un flux d'entrée à partir du clavier, pas à un fichier. 

Source: http://www.oopweb.com/Java/Documents/JavaNotes/Volume/chap84/ch84_3.html

74
Mr. Black

Tout d’abord, vous devez comprendre le "streaming" en Java car tous les "lecteurs" en Java reposent sur ce concept.

Streaming de fichier

La diffusion de fichiers est effectuée par l’objet FileInputStream en Java.

// it reads a byte at a time and stores into the 'byt' variable
int byt;
while((byt = fileInputStream.read()) != -1) {
    fileOutputStream.write(byt);
} 

Cet objet lit en fait un octet (8 bits) à la fois et l’écrit dans le fichier donné.

Une application pratique utile consiste à travailler avec des fichiers binaires/données bruts, tels que des images ou des fichiers audio (utilisez AudioInputStream au lieu de FileInputStream pour les fichiers audio) . Par contre, pour les fichiers texte, il est très gênant ralentir, en raison du passage en boucle d'un octet à la fois, puis effectuer un traitement et stocker le dernier octet traité est fastidieux et prend beaucoup de temps.

Vous devez également fournir le jeu de caractères du fichier texte, c'est-à-dire si les caractères sont en latin ou chinois, etc. Sinon, le programme décodera et encodera 8 bits à la fois et vous Je verrais des caractères étranges imprimés à l'écran ou écrits dans le fichier de sortie (si un caractère est supérieur à 1 octet).

Lecture de fichier  

C’est simplement une façon élégante de dire "Transmission en continu de fichiers" avec prise en charge du jeu de caractères incluse (c’est-à-dire qu’il n’est pas nécessaire de définir le jeu de caractères, comme auparavant).

La classe FileReader est spécialement conçue pour traiter les fichiers texte . Comme vous l'avez vu précédemment, le streaming de fichiers est préférable pour traiter des données binaires brutes, mais pour des raisons de texte, il n'est pas aussi efficace. .

Les gars de Java ont donc ajouté la classe FileReader pour traiter spécifiquement les fichiers texte. Il lit 2 octets (ou 4 octets, selon le jeu de caractères) à la fois. Une amélioration remarquable par rapport à la précédente FileInputStream !!

donc l'opération de streaming est comme ça,

int c;
while ( (c = fileReader.read()) != -1) { // some logic }

Veuillez noter que les deux classes utilisent une variable entière pour stocker la valeur extraite du fichier d'entrée (ainsi, chaque caractère est converti en un entier lors de la récupération, puis retourné au caractère lors de son stockage).

Le seul avantage ici est que, puisque cette classe traite les fichiers texte, vous n'avez pas à spécifier le jeu de caractères du fichier texte et quelques autres propriétés. Il fournit fondamentalement une solution prête à l'emploi, pour la plupart des cas de traitement de fichiers texte. Il prend également en charge l'internationalisation et la localisation.

Mais encore une fois, il est encore trop lent (la lecture image 2 octets à la fois et en boucle!).

Mise en mémoire tampon des flux  

Pour résoudre le problème de la boucle continue sur un octet ou deux. Les gars de Java ont ajouté une autre fonctionnalité spectaculaire. "Pour créer un tampon de données, avant traitement."

Le concept est à peu près le même lorsqu'un utilisateur diffuse une vidéo sur YouTube. Une vidéo est mise en mémoire tampon avant la lecture, afin de fournir une expérience de visionnage vidéo sans faille. (Cependant, le navigateur continue à mettre en mémoire tampon jusqu'à ce que toute la vidéo soit mise en mémoire tampon à l'avance.) La même technique est utilisée par la classe BufferedReader

L'objet BufferedReader prend en entrée un objet FileReader qui contient toutes les informations nécessaires sur le fichier texte à lire. (comme le chemin du fichier et le jeu de caractères.) 

BufferedReader br = new BufferedReader( new FileReader("example.txt") );

Lorsque l'instruction "read" est donnée à l'objet BufferedReader, il utilise l'objet FileReader pour lire les données du fichier. Lorsqu'une instruction est donnée, l'objet FileReader lit 2 (ou 4) octets à la fois et renvoie les données au BufferedReader et le lecteur continue à le faire jusqu'à ce qu'il clique sur '\ n' ou '\ r\n '(le symbole de fin de ligne). Une fois la ligne mise en mémoire tampon, le lecteur attend patiemment jusqu’à l’instruction de mettre en mémoire tampon la ligne suivante.

Pendant ce temps, l’objet BufferReader crée un emplacement mémoire spécial ("RAM"), et stocke toutes les données extraites de l’objet FileReader.

// this variable points to the buffered line
String line;

// Keep buffering the lines and print it.
while ((line = br.readLine()) != null) {
    printWriter.println(line);
}

Maintenant, ici, au lieu de lire 2 octets à la fois, une ligne entière est extraite et stockée quelque part dans la RAM. Lorsque vous avez terminé de traiter les données, vous pouvez stocker la ligne complète sur le disque dur. Ainsi, le processus est bien plus rapide que 2 octets à la fois.

Mais encore une fois, pourquoi devons-nous passer l’objet FileReader à BufferReader? Ne pouvons-nous pas simplement dire "tamponner ce fichier" et BufferReader se chargera du reste? cela ne serait-il pas doux?

Eh bien, la classe BufferReader est créée de manière à ce qu’elle sache uniquement comment créer un tampon et stocker les données entrantes. Peu importe la raison pour laquelle les données proviennent.

Cela étant dit, lorsque vous fournissez l'objet FileReader en tant qu'entrée, il met le fichier en mémoire tampon, de la même manière que si vous fournissez l'objet InputStreamReader, il met en mémoire tampon les données d'entrée Terminal/Console jusqu'à ce qu'il atteigne une nouvelle ligne. symbole. tel que,

// Object that reads console inputs
InputStreamReader console = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(console);
System.out.println(br.readLine());

De cette façon, vous pouvez lire (ou mettre en tampon) plusieurs flux avec la même classe BufferReader, tels que des fichiers texte, des consoles, des imprimantes, des données de réseau, etc., et vous devez simplement vous rappeler,

 bufferedReader.readLine();

pour imprimer ce que vous avez tamponné.

92
Mehul Katpara

BufferedReader nécessite un Reader, dont FileReader - il descend de InputStreamReader, qui descend de Reader.

0
Rohit Goyal