1 00:00:00,490 --> 00:00:04,960 Bonjour. Dans cette séquence nous allons parler de la 2 00:00:05,160 --> 00:00:07,770 bibliothèque de Stream qui est fournie de base avec Pharo. 3 00:00:09,340 --> 00:00:11,760 Nous verrons ce que sont les streams et comment les 4 00:00:11,960 --> 00:00:13,460 utiliser, et dans quels cas ils peuvent être utiles. 5 00:00:15,070 --> 00:00:16,060 Alors qu'est-ce qu'un stream ? 6 00:00:16,530 --> 00:00:18,690 Un stream, c'est un objet qui permet 7 00:00:21,420 --> 00:00:24,390 d'itérer sur une séquence d'éléments. 8 00:00:24,590 --> 00:00:28,140 Cette séquence, ça peut être une collection en mémoire, 9 00:00:28,830 --> 00:00:33,530 ça peut être un flux réseau, ça peut être un fichier 10 00:00:33,730 --> 00:00:38,410 ou autres. Un stream garde en mémoire la 11 00:00:38,610 --> 00:00:41,390 position courante, et au fur à mesure de l'utilisation du 12 00:00:41,590 --> 00:00:45,300 stream on va pouvoir avancer ou reculer pour pouvoir lire 13 00:00:45,500 --> 00:00:46,660 ou écrire des éléments dans le stream. 14 00:00:48,030 --> 00:00:51,400 Un aperçu de l'API des streams. 15 00:00:51,600 --> 00:00:56,080 Pour créer un stream, il y a quelques objets sur lesquels 16 00:00:56,280 --> 00:00:59,750 on peut utiliser les messages readStream et writeStream, 17 00:01:00,940 --> 00:01:02,850 pour créer des streams à partir de ces objets-là. 18 00:01:03,220 --> 00:01:06,090 Par exemple à partir d'un fichier ou à partir d'une 19 00:01:06,290 --> 00:01:10,450 collection on peut créer des streams de cette façon-là. 20 00:01:12,380 --> 00:01:16,000 Ce message-là, "streamContents" s'envoie à une collection 21 00:01:16,850 --> 00:01:19,040 et prend un block en paramètre qui reçoit un stream. 22 00:01:19,840 --> 00:01:22,450 Et l'utilisation de ce stream au sein de ce block là va 23 00:01:22,750 --> 00:01:27,430 créer une collection qui sera finalement retournée par la 24 00:01:27,630 --> 00:01:30,170 méthode. On verra l'utilisation de cette méthode-là à la fin. 25 00:01:32,400 --> 00:01:35,650 Dans ces cas-là on demande directement à une classe de 26 00:01:35,850 --> 00:01:37,470 streams, soit readStream, soit writeStream, soit 27 00:01:37,670 --> 00:01:42,610 rewriteStream, de créer une nouvelle instance par rapport à une collection. 28 00:01:44,830 --> 00:01:48,430 Les 3 méthodes qui sont là permettent de lire des 29 00:01:48,630 --> 00:01:53,210 éléments, donc un ou plusieurs jusqu'à une certaine limite. 30 00:01:54,220 --> 00:01:58,150 Et les 2 éléments qui sont là permettent d'écrire un 31 00:01:58,350 --> 00:02:00,240 élément ou une collection d'éléments dans le stream. 32 00:02:01,250 --> 00:02:04,500 Alors voici quelques exemples permettant de lire dans un stream. 33 00:02:04,700 --> 00:02:06,340 Première étape, on crée un stream. 34 00:02:06,890 --> 00:02:11,800 Ici, on crée un stream en lecture à partir d'une collection. 35 00:02:12,070 --> 00:02:14,760 Cette collection contient les lettres de l'alphabet entre 36 00:02:14,960 --> 00:02:19,790 A à F, donc avec un caractère par élément dans la collection. 37 00:02:20,280 --> 00:02:22,660 On créé un stream sur cette collection-là et on va 38 00:02:22,860 --> 00:02:25,680 regarder les caractères un par un. 39 00:02:25,880 --> 00:02:29,000 Une fois qu'on a notre stream, la première chose qu'on 40 00:02:29,200 --> 00:02:32,000 peut faire, c'est envoyer le message next qui va nous 41 00:02:32,200 --> 00:02:35,160 retourner l'élément juste après la position courante. 42 00:02:35,800 --> 00:02:38,130 Dès l'initialisation du stream, la position courante c'est 43 00:02:38,330 --> 00:02:41,290 0 donc on se situe au début du stream, donc next retourne 44 00:02:41,490 --> 00:02:43,850 au début le premier élément, c'est-à-dire A. 45 00:02:46,000 --> 00:02:50,000 Si j'appelle next à ce moment-là je vais obtenir B, puis 46 00:02:50,200 --> 00:02:53,380 C, puis D, et caetera, un par un en appelant next, next, 47 00:02:53,580 --> 00:02:57,000 next on fait évoluer la position d'un cran à chaque fois. 48 00:02:58,160 --> 00:03:01,340 Si j'appelle next une première fois et que j'obtiens A, 49 00:03:01,820 --> 00:03:06,350 ensuite je peux envoyer le message upTo et un élément, 50 00:03:06,800 --> 00:03:09,300 et cette méthode-là va me retourner tous les éléments 51 00:03:09,500 --> 00:03:12,900 entre la position courante et l'élément que j'ai passé en paramètre. 52 00:03:13,870 --> 00:03:18,100 Donc là si avant j'avais A, je me situe en position 1 et 53 00:03:18,300 --> 00:03:20,670 si j'envoie le message upTo D, il va me retourner tout ce 54 00:03:20,870 --> 00:03:25,760 qu'il y a entre la position courante et D, c'est-à-dire B et C. 55 00:03:25,960 --> 00:03:29,630 D est consommé par le stream, c'est-à-dire que maintenant 56 00:03:29,830 --> 00:03:33,670 le stream se situe juste après D mais D n'est pas retourné. 57 00:03:34,310 --> 00:03:38,930 Stream position nous donne la position en cours. 58 00:03:39,230 --> 00:03:40,680 La position commence à 0. 59 00:03:40,900 --> 00:03:45,070 0, c'est avant le premier élément, donc 0, 1, 2, 3, 60 00:03:45,490 --> 00:03:48,940 4, on se situe bien juste avant le E et après le D. 61 00:03:50,930 --> 00:03:54,880 À ce moment-là si j'envoie le message upToEnd au stream, 62 00:03:55,080 --> 00:03:57,070 je vais obtenir tous les éléments qui se situent entre la 63 00:03:57,270 --> 00:04:01,000 position courante et la fin du stream, c'est-à-dire E et 64 00:04:02,340 --> 00:04:05,580 F. Donc on voit que le stream maintient une position 65 00:04:05,780 --> 00:04:08,750 courante que je peux faire avancer grâce à quelques méthodes. 66 00:04:08,950 --> 00:04:11,730 De la même façon on peut écrire dans un stream. 67 00:04:11,930 --> 00:04:14,050 La première étape encore une fois, c'est créer le stream. 68 00:04:16,060 --> 00:04:19,890 Array new: 6 me permet de créer un tableau vide mais de taille 6. 69 00:04:20,690 --> 00:04:23,350 J'envoie le message writeStream dessus pour créer un 70 00:04:23,550 --> 00:04:25,420 stream sur ce tableau-là, de façon à pouvoir remplir le 71 00:04:25,620 --> 00:04:28,120 tableau petit à petit grâce à mon stream. 72 00:04:28,320 --> 00:04:30,710 Je stocke ce stream dans la variable stream et je 73 00:04:30,910 --> 00:04:34,140 commence par envoyer le message nextPut 1, qui prend un 74 00:04:34,340 --> 00:04:38,420 élément et ajoute cet élément en position courante dans le stream. 75 00:04:38,700 --> 00:04:43,600 Maintenant, mon tableau contient un 1 suivi de 5 cases vides. 76 00:04:46,360 --> 00:04:49,030 Le message nextPutAll, quant à lui, prend une collection 77 00:04:49,820 --> 00:04:53,170 d'objets à mettre les uns après les autres dans le stream. 78 00:04:54,530 --> 00:04:59,200 Après l'envoi de ce message nextPutAll à mon stream, j'obtiens 79 00:04:59,400 --> 00:05:03,200 le tableau qui contient un résultat de mon nextPut 80 00:05:03,880 --> 00:05:06,420 précédent suivi de 4, 8, 2, 6, 7, 81 00:05:08,770 --> 00:05:09,950 résultats du nextPutAll. 82 00:05:11,480 --> 00:05:14,440 Donc les streams sont particulièrement utiles et 83 00:05:14,640 --> 00:05:17,930 efficaces pour lire et écrire dans les collections d'objets. 84 00:05:19,450 --> 00:05:21,290 Je peux aussi lire et écrire dans des fichiers. 85 00:05:21,820 --> 00:05:25,750 Là, je montre un exemple de comment écrire dans un 86 00:05:25,950 --> 00:05:27,350 nouveau fichier qui n'existe pas encore. 87 00:05:29,890 --> 00:05:32,420 Dans la chaîne de caractères ici j'indique le nom du fichier. 88 00:05:33,860 --> 00:05:36,670 En envoyant à une chaîne de caractères le message 89 00:05:37,900 --> 00:05:41,820 asFileReference, je créé une référence vers un fichier. 90 00:05:42,020 --> 00:05:44,000 Là c'est un fichier qui n'existe pas encore mais je peux 91 00:05:44,200 --> 00:05:45,460 quand même avoir une référence dessus. 92 00:05:46,790 --> 00:05:51,310 J'ai une référence vers un fichier et le point txt et j'envoie 93 00:05:51,510 --> 00:05:55,220 le message write Stream sur ce fichier 94 00:05:56,260 --> 00:06:00,000 histoire d'avoir un stream en écriture vers ce fichier 95 00:06:00,200 --> 00:06:03,560 qui n'existe pas encore. Dès qu'on va écrire dans le 96 00:06:03,760 --> 00:06:04,880 stream, le fichier va être recréé. 97 00:06:06,550 --> 00:06:09,150 Maintenant que j'ai mon stream, j'envoie le message 98 00:06:09,440 --> 00:06:12,490 nextPutAll avec une chaîne de caractères et ce message 99 00:06:12,690 --> 00:06:15,320 nextPutAll va écrire caractère après caractère chaque 100 00:06:15,520 --> 00:06:16,800 élément de ma chaîne de caractères. 101 00:06:17,070 --> 00:06:18,530 Il va écrire le H, puis le E, puis le L, et cetera. 102 00:06:18,730 --> 00:06:23,620 A la fin, je 103 00:06:23,820 --> 00:06:27,360 ferme mon stream pour indiquer au système d'exploitation 104 00:06:27,560 --> 00:06:31,520 que j'ai fini d'écrire dans le fichier, et qu'il peut lui 105 00:06:31,720 --> 00:06:36,130 écrire l'ensemble sur le support de stockage et fermer le 106 00:06:36,330 --> 00:06:37,090 pointeur sur le fichier. 107 00:06:38,050 --> 00:06:42,830 Maintenant que j'ai écrit dans ce fichier, je peux avoir envie de le lire. 108 00:06:43,030 --> 00:06:47,320 De la même façon, j'ai le nom du fichier sous forme d'une 109 00:06:47,520 --> 00:06:52,420 chaînes de caractères, asFile Reference qui me 110 00:06:52,620 --> 00:06:55,950 permet de créer une référence vers ce fichier-là, 111 00:06:57,960 --> 00:07:02,520 et read stream qui me permet d'ouvrir un flux en lecture, 112 00:07:02,720 --> 00:07:05,850 qui permet d'ouvrir un stream en lecture sur ce fichier-là. 113 00:07:08,170 --> 00:07:10,770 Avec next, je récupère le premier élément dans le stream. 114 00:07:11,000 --> 00:07:15,000 J'avais écrit "Hello Pharo", le premier élément, c'est H, H majuscule. 115 00:07:15,670 --> 00:07:19,590 Et avec upToEnd, je récupère tous les caractères entre la 116 00:07:19,790 --> 00:07:22,210 position courante, c'est-à-dire juste après le H avant le 117 00:07:22,410 --> 00:07:25,590 E et jusqu'à la fin du stream, jusqu'à la fin du fichier. 118 00:07:26,400 --> 00:07:29,670 J'obtiens'ello Pharo'sans le H puisque je l'ai déjà 119 00:07:29,870 --> 00:07:32,660 récupéré grâce au next précédent. 120 00:07:33,870 --> 00:07:37,060 On peut créer des collections en utilisant des streams. 121 00:07:37,480 --> 00:07:40,070 Ça c'est très utile quand on veut créer des collections 122 00:07:40,270 --> 00:07:42,330 et qu'il nous faut du code pour choisir ce qu'on va 123 00:07:42,530 --> 00:07:44,380 mettre dans la collection petit à petit. 124 00:07:45,680 --> 00:07:47,640 Là, je veux créer une OrderedCollection 125 00:07:51,110 --> 00:07:53,310 en envoyant des messages à un stream. 126 00:07:53,510 --> 00:07:57,510 À partir de ma classe OrderedCollection, je fais une 127 00:07:57,710 --> 00:08:01,750 nouvelle instance, j'en fais un flux en écriture 128 00:08:02,570 --> 00:08:06,430 et avec le message next put, j'ajoute l'élément 1 dans mon stream. 129 00:08:06,630 --> 00:08:10,650 Maintenant quand je vais faire streamContents, je vais 130 00:08:10,850 --> 00:08:13,690 obtenir une instance de la classe OrderedCollection qui 131 00:08:13,890 --> 00:08:14,840 contient uniquement la valeur 1. 132 00:08:16,320 --> 00:08:18,710 Ces 3 expressions peuvent s'écrire plus simplement comme 133 00:08:18,910 --> 00:08:22,060 on le voit en-dessous. En envoyant le message 134 00:08:22,320 --> 00:08:25,020 "streamContents" à la classe de collection qui nous 135 00:08:25,220 --> 00:08:27,520 intéresse, donc ici c'est OrderedCollection, j'envoie ce 136 00:08:27,720 --> 00:08:30,490 message "streamContents" à OrderedCollection, je lui 137 00:08:30,690 --> 00:08:34,720 passe en paramètre un block qui prend un stream en paramètre. 138 00:08:35,910 --> 00:08:37,900 Au sein de ce block, je vais utiliser le stream pour 139 00:08:38,100 --> 00:08:40,020 remplir ma collection petit à petit et quand le block se 140 00:08:40,220 --> 00:08:41,320 termine j'obtiens ma collection. 141 00:08:42,610 --> 00:08:47,380 Dans le block, je fais "stream nextPut 1", j'ajoute 142 00:08:47,580 --> 00:08:51,910 1 dans mon stream qui va l'ajouter dans la collection. 143 00:08:52,240 --> 00:08:54,610 Quand "streamContents" quitte, donc quand l'ensemble de 144 00:08:54,810 --> 00:08:57,210 cette expression se termine, je vais obtenir une 145 00:08:57,410 --> 00:08:59,340 OrderedCollection qui contient 1. 146 00:08:59,540 --> 00:09:03,320 StreamContents c'est utile pour créer des collections à partir de rien. 147 00:09:04,480 --> 00:09:07,580 Dans cette séquence, nous avons découvert l'API de stream. 148 00:09:07,780 --> 00:09:09,890 Il y a énormément de méthodes dans cette API que je vous 149 00:09:10,090 --> 00:09:12,170 invite à aller découvrir en naviguant dans les classes 150 00:09:12,370 --> 00:09:13,920 grâce au navigateur de codes Nautilus. 151 00:09:14,490 --> 00:09:17,540 Un stream peut lire et écrire dans des collections d'éléments 152 00:09:18,000 --> 00:09:21,770 en mémoire, dans des fichiers, sur le réseau et d'autres éléments encore. 153 00:09:23,790 --> 00:09:27,800 Un stream a toujours une position courante, c'est important. 154 00:09:28,000 --> 00:09:30,060 La position courante sépare les éléments du passé des 155 00:09:30,260 --> 00:09:33,110 éléments du futur, et en fait évoluer cette position 156 00:09:33,310 --> 00:09:37,840 courante à chaque fois qu'on va vouloir lire ou écrire dans le flux. 157 00:09:38,040 --> 00:09:40,370 Enfin, les streams peuvent servir à créer des nouvelles collections.