JavaRush /Blog Java /Random-FR /E/S en Java. Classes FileInputStream, FileOutputStream, B...

E/S en Java. Classes FileInputStream, FileOutputStream, BufferedInputStream

Publié dans le groupe Random-FR
Bonjour! Dans la conférence d'aujourd'hui, nous poursuivrons la conversation sur les flux d'entrée et de sortie en Java, ou Java I/O (« entrée-sortie ») en abrégé. Ce n'est pas la première conférence sur ce sujet, et ce ne sera pas la dernière :) Il se trouve que Java en tant que langage offre de nombreuses possibilités pour travailler avec les entrées/sorties. Il existe de nombreuses classes qui implémentent cette fonctionnalité, nous les avons donc divisées en plusieurs conférences afin que vous ne soyez pas confus au début :) E/S en Java.  Classes FileInputStream, FileOutputStream, BufferedInputStream - 1Dans les conférences précédentes, nous avons abordé BufferedReader , ainsi que les classes abstraites InputStream & OutputStream et plusieurs descendance. Aujourd'hui, nous allons examiner 3 nouvelles classes : FileInputStream , FileOutputStream et BufferedInputStream .

Classe FileOutputStream

L'objectif principal de la classe FileOutputStream est d'écrire des octets dans un fichier. Rien de compliqué :) FileOutputStream est l'une des implémentations de la classe abstraite OutputStream . Dans le constructeur, les objets de cette classe prennent soit le chemin d'accès au fichier cible (dans lequel les octets doivent être écrits), soit un objet de la classe File. Regardons les deux exemples :
public class Main {

   public static void main(String[] args) throws IOException {


       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Lors de la création d'un objet, Filenous avons spécifié dans le constructeur le chemin où il doit se trouver. Il n'est pas nécessaire de le créer à l'avance : s'il n'existe pas, le programme le créera lui-même. Vous pouvez vous passer de créer un objet supplémentaire et simplement passer une chaîne avec l'adresse :
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Le résultat dans les deux cas sera le même. Nous pouvons ouvrir notre fichier et y voir :

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
Il y a cependant une mise en garde ici. Essayez d'exécuter le code de l'exemple ci-dessus plusieurs fois de suite, puis regardez le fichier et répondez à la question : combien de lignes voyez-vous écrites dedans ? Juste un. Mais vous avez exécuté le code plusieurs fois. Cependant, il s’avère que les données ont été écrasées à chaque fois, remplaçant les anciennes. Que se passe-t-il si nous n’en sommes pas satisfaits et avons besoin d’un enregistrement séquentiel ? Que se passe-t-il si nous voulons écrire notre message d'accueil dans un fichier trois fois de suite ? Tout est simple ici. Étant donné que le langage lui-même ne peut pas savoir de quel type de comportement nous avons besoin dans chaque cas, FileOutputStreamvous pouvez transmettre un paramètre supplémentaire au constructeur - boolean append. Si sa valeur est true , les données seront écrites à la fin du fichier. Si false (et la valeur par défaut est false ), les anciennes données seront effacées et de nouvelles données seront écrites. Testons et exécutons notre code modifié trois fois :
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!\r\n";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Résultat dans le fichier :

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Autre chose! Gardez cette fonctionnalité à l’esprit lorsque vous utilisez des classes d’E/S. À un moment donné, je devais m'asseoir pendant des heures sur des tâches pour comprendre où allaient mes anciennes données des fichiers :) Et bien sûr, comme dans le cas des autres classes d'E/S, n'oubliez pas de libérer des ressources via le close().

Classe FileInputStream

La classe a FileInputStreamle but opposé : lire les octets d’un fichier. Tout comme FileOutputStreaml'hérite OutputStream, cette classe dérive de la classe abstraite InputStream. Écrivons plusieurs lignes de texte dans notre texte « test.txt » :

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
E/S en Java.  Classes FileInputStream, FileOutputStream, BufferedInputStream - 2 C'est ce que représente l'implémentation de la lecture des données d'un fichier à l'aide FileInputStreamde :
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Nous lisons un octet du fichier, convertissons les octets lus en caractères et les envoyons à la console. Et voici le résultat dans la console :

So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters

Classe BufferedInputStream

Je pense qu'étant donné les connaissances acquises lors des cours précédents, vous pouvez facilement comprendre pourquoi le cours est nécessaire BufferedInputStreamet quels avantages il présente par rapport FileInputStream:) Nous avons déjà rencontré des flux tamponnés, alors essayez de deviner (ou de vous souvenir) avant de continuer la lecture :) Flux tamponnés sont nécessaires principalement pour optimiser les E/S. L'accès à une source de données, comme la lecture d'un fichier, est une opération gourmande en performances. Et accéder au fichier pour lire un octet à chaque fois est un gaspillage. Par conséquent, BufferedInputStreamil lit les données non pas un octet à la fois, mais par blocs et les stocke temporairement dans un tampon spécial. Cela nous permet d'optimiser le fonctionnement du programme en réduisant le nombre d'accès au fichier. Voyons à quoi cela ressemble :
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Ici, nous avons créé un objet BufferedInputStream. Il accepte un objet ou l'un de ses successeurs en entrée InputStream, donc le précédent FileInputStreamfera l'affaire. Il prend la taille du tampon en octets comme paramètre supplémentaire. Désormais, grâce à cela, les données seront lues à partir du fichier non pas un octet à la fois, mais 200 à la fois ! Imaginez à quel point nous avons réduit le nombre d'accès aux fichiers. Pour comparer les performances, vous pouvez prendre un gros fichier texte de plusieurs mégaoctets et comparer le temps qu'il faut pour le lire et le sortir sur la console en millisecondes en utilisant FileInputStreamet BufferedInputStream. Voici les deux exemples de code :
public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}



public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");


       int i;

       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}
Lors de la lecture d'un fichier de 1,5 Mo sur mon ordinateur, FileInputStreamil a fait le travail en environ 3 500 millisecondes, mais ici, BufferedInputStreamil a fait le travail en environ 1 700 millisecondes. Comme vous pouvez le voir, le flux mis en mémoire tampon a optimisé les performances du programme de 2 fois ! :) Nous continuerons à étudier les classes I/O - à bientôt !
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION