1 00:00:02,419 --> 00:00:10,640 Vale, pues si no tenéis así ninguna duda en particular, de la que queréis que hablamos antes de arrancar, vamos a hacer un pequeño repaso sobre el tema 10. 2 00:00:12,240 --> 00:00:22,420 Visteis, el otro día os dejé grabado, me habíais comentado una de las tareas, hice una pequeña grabación el miércoles y la dejé colgada junto al resto de vídeos, supongo que veríais el mensaje en el foro. 3 00:00:22,420 --> 00:00:25,359 y bueno, el plan un poco es 4 00:00:25,359 --> 00:00:29,120 ver el tema 10 hoy, hacer un repaso 5 00:00:29,120 --> 00:00:32,100 de la teoría y como os decía 6 00:00:32,100 --> 00:00:34,560 el tema 11 y el tema 12, interfaces gráficas 7 00:00:34,560 --> 00:00:38,439 y bases de datos, aunque las vamos a ir abriendo en las fechas 8 00:00:38,439 --> 00:00:41,200 que yo creo recordar que ya abríamos mañana 9 00:00:41,200 --> 00:00:44,259 el último tema de bases de datos, en verdad nos quedan 10 00:00:44,259 --> 00:00:46,960 dos semanas, la semana que viene es la última tutoría 11 00:00:46,960 --> 00:00:49,420 bueno, de estos dos temas 12 00:00:49,420 --> 00:00:52,979 como comentaba en el mensaje 13 00:00:52,979 --> 00:00:55,799 en el foro, de cara al examen será 14 00:00:55,799 --> 00:00:58,960 testimonial si preguntamos alguna cosita. No os digo que no 15 00:00:58,960 --> 00:01:01,380 entre porque son contenidos del curso 16 00:01:01,380 --> 00:01:04,900 pero será muy testimonial. Entonces si 17 00:01:04,900 --> 00:01:07,939 andáis sobrados de tiempo, que supongo que no, echarle 18 00:01:07,939 --> 00:01:11,079 un ojo y si no, centraros hasta colecciones 19 00:01:11,079 --> 00:01:13,760 y un poquito también este tema y ya está 20 00:01:13,760 --> 00:01:16,859 de cara a lo que es el examen y ya tendréis tiempo de ver 21 00:01:16,859 --> 00:01:18,819 el resto de cosas porque además 22 00:01:18,819 --> 00:01:21,900 el año que viene tenéis una asignatura 23 00:01:21,900 --> 00:01:24,939 que es acceso a datos, que habla mucho de 24 00:01:24,939 --> 00:01:28,000 cómo conectarse a base de datos y todo esto 25 00:01:28,000 --> 00:01:30,719 es decir, hace un desarrollo más amplio de lo que trata 26 00:01:30,719 --> 00:01:33,060 el tema que abriría mañana en principio 27 00:01:33,060 --> 00:01:36,859 interfaces gráficas, pues la verdad 28 00:01:36,859 --> 00:01:40,180 es que de escritorio, bueno ahí están las librerías 29 00:01:40,180 --> 00:01:42,379 si permite utilizarlas, pero 30 00:01:42,379 --> 00:01:44,739 el acceso a Java 31 00:01:44,739 --> 00:01:48,079 o sea, el desarrollar ventanas en Java 32 00:01:48,079 --> 00:01:51,180 no es lo más típico, entonces bueno 33 00:01:51,180 --> 00:01:53,760 de todas formas sí que es interesante porque bueno pues 34 00:01:53,760 --> 00:01:57,219 se aprende un poco, la semana que viene 35 00:01:57,219 --> 00:01:59,920 pegamos un pequeño repaso, hacemos alguna cosita 36 00:01:59,920 --> 00:02:03,439 se aprende un poco como puede ser la programación 37 00:02:03,439 --> 00:02:06,120 dirigida a eventos, eventos bueno que se generan 38 00:02:06,120 --> 00:02:09,240 en el momento en el que pinchamos por ejemplo en un botón con un ratón 39 00:02:09,240 --> 00:02:12,020 o pasamos el ratón por encima de algún 40 00:02:12,020 --> 00:02:15,199 control o minimizamos la pantalla 41 00:02:15,199 --> 00:02:18,780 todas estas cosas, digamos que son eventos que se producen sobre la aplicación 42 00:02:18,780 --> 00:02:21,800 se detectan y como consecuencia que se genera ese evento 43 00:02:21,800 --> 00:02:24,860 nos permite ejecutar una zona de código 44 00:02:24,860 --> 00:02:26,740 que es donde ponemos lo que queremos que pase 45 00:02:26,740 --> 00:02:29,300 es decir, pinchamos un botón, pues se genera un evento 46 00:02:29,300 --> 00:02:31,180 como consecuencia de ese evento 47 00:02:31,180 --> 00:02:36,379 el flujo de ejecución del programa pasará a un determinado método 48 00:02:36,379 --> 00:02:38,379 y en ese método hacemos lo que queremos que pase 49 00:02:38,379 --> 00:02:42,000 si ha sido pulsar un botón que es salvar una información en una base de datos 50 00:02:42,000 --> 00:02:46,000 pues ahí codificaremos el guardar esos datos en la base 51 00:02:46,000 --> 00:02:49,180 de datos o lo que corresponda según el enunciado 52 00:02:49,180 --> 00:02:53,800 pero bueno, eso es la semana que viene, en esta semana vamos a hablar 53 00:02:53,800 --> 00:02:57,520 de los flujos, que es lo que tenemos en el tema 10 54 00:02:57,520 --> 00:03:02,039 y mirad aquí, en el tema 10 55 00:03:02,039 --> 00:03:06,120 vamos a ir como siempre apoyándonos 56 00:03:06,120 --> 00:03:10,120 en el código con el entorno de desarrollo, no sé si entiendo que habréis tenido 57 00:03:10,120 --> 00:03:15,439 la oportunidad de leerlo. Y bueno, aquí hay un esquema que puede ser bastante interesante 58 00:03:15,439 --> 00:03:21,740 para ponernos un poco en situación. Por clasificar un poco lo que son los flujos. 59 00:03:21,819 --> 00:03:29,460 Los flujos de comunicación es la vía, yo siempre lo comento como si fuera una tubería 60 00:03:29,460 --> 00:03:35,800 que conecta nuestro programa con el exterior. En un extremo está conectada esa tubería 61 00:03:35,800 --> 00:03:39,719 a nuestro programa, como os digo, y en el otro extremo, pues 62 00:03:39,719 --> 00:03:43,759 a la fuente con la que nos estamos comunicando. Podemos tener flujos 63 00:03:43,759 --> 00:03:47,199 que sean de entrada, es decir, para capturar información en nuestro programa 64 00:03:47,199 --> 00:03:51,800 y flujos que sean de salida, para ser capaz de transmitir información 65 00:03:51,800 --> 00:03:55,800 desde nuestro programa al exterior. Y estos flujos 66 00:03:55,800 --> 00:03:59,879 pues la fuente con la que nos comunicamos desde el programa 67 00:03:59,879 --> 00:04:04,020 pues puede ser teclado, pues sería un flujo de entrada 68 00:04:04,020 --> 00:04:28,199 el System.in este que venimos encasulando todo el tiempo en la clase Scanner, pues es un flujo de entrada en particular para ubicarlo dentro de todo este esquema, sería un InputStream, es como está codificado el System.in, como está adaptado, podría ser la salida estándar a pantalla, 69 00:04:28,199 --> 00:04:32,360 o bien la salida de errores del programa que nos lo saca a consola, a pantalla 70 00:04:32,360 --> 00:04:36,079 eso sería un flujo de programa, comunica nuestro código con el exterior 71 00:04:36,079 --> 00:04:40,300 en este caso con la pantalla, que yo creo que es un print stream 72 00:04:40,300 --> 00:04:44,360 como está implementado, pues fijaros si venimos por aquí por la zona del output stream 73 00:04:44,360 --> 00:04:48,199 tenemos aquí el print stream, pues cuando hacemos un system out 74 00:04:48,199 --> 00:04:51,819 el system out está 75 00:04:51,819 --> 00:04:56,399 encasulado dentro de un print stream, con lo cual los println estos que ponemos 76 00:04:56,399 --> 00:04:59,439 están desarrollados en esta clase, en la librería de Java. 77 00:05:02,360 --> 00:05:06,959 Más flujos con los que comunicamos nuestro programa, pues es con los ficheros. 78 00:05:07,300 --> 00:05:11,540 Tenemos ficheros en disco que podemos querer leer desde el programa o escribir, 79 00:05:11,779 --> 00:05:15,120 que es donde se centra principalmente este tema. 80 00:05:16,079 --> 00:05:21,139 Entonces tenemos clases que nos facilitan el manejo de la lectura de ficheros 81 00:05:21,139 --> 00:05:22,420 o de escritura de ficheros. 82 00:05:22,420 --> 00:05:41,699 Entonces, por ejemplo, por aquí tenemos FileInputStream, ¿veis? Para leer, ahora hablamos de lo que significa stream y no significa, pero bueno, aquí tenemos que empieza esta clase con el nombre file, pues para leer desde ficheros o para escribir en ellos, pues tenemos la opción de FileOutputStream. 83 00:05:41,699 --> 00:05:47,199 por aquí tenemos otra que es FileWriter 84 00:05:47,199 --> 00:05:50,000 me parece, mirad, aquí tenemos FileWriter 85 00:05:50,000 --> 00:05:55,079 luego, no son estas las únicas vías por las que 86 00:05:55,079 --> 00:05:58,959 podemos comunicar nuestro programa con el exterior, a través de pantalla 87 00:05:58,959 --> 00:06:03,220 o teclado, o a través de ficheros, otro mecanismo 88 00:06:03,220 --> 00:06:07,139 podría ser, aunque esto quizás no estaría tanto enfocado a los 89 00:06:07,139 --> 00:06:11,100 flujos de datos, podría ser a través de bases de datos, como el último tema 90 00:06:11,100 --> 00:06:16,060 o el año que viene que lo veréis en desarrollo de interfaces, como os comentaba antes. 91 00:06:17,199 --> 00:06:23,620 Y luego es típico en el mundo actual que abramos el navegador y nos conectemos a un servidor web 92 00:06:23,620 --> 00:06:31,699 o hagamos una consulta a un servidor DNS, una transferencia de ficheros a través de servidores FTP. 93 00:06:32,740 --> 00:06:38,699 Pues estas comunicaciones entre dos aplicaciones, una la que es la servidora y otra la que es la cliente, 94 00:06:38,699 --> 00:07:01,300 Sería el servidor web, por ejemplo, de marca, que lo tiene en sus instalaciones marca, tendría un servidor web en un ordenador, servidor, y nosotros nos conectaríamos con un cliente que sería nuestro navegador, pues para que se establezca esta comunicación entre el navegador y el servidor web, se genera un flujo de datos también que comunica estas dos aplicaciones, que eso sería un socket. 95 00:07:01,300 --> 00:07:08,300 Y esto lo veréis el año que viene en la asignatura de programación de servicios y procesos. 96 00:07:08,699 --> 00:07:19,759 Pero una vez más estaríamos comunicando dos aplicaciones, una de ellas podría estar desarrollada en Java y la otra no, o las dos en Java o ninguna en Java podría ser. 97 00:07:20,660 --> 00:07:37,980 Entonces en Java, pensando en Java, pues también se generaría un flujo de comunicación que pone en contacto nuestra aplicación con una fuente externa de la cual recibimos la página web del servidor marca, por ejemplo, si estamos haciendo las veces de cliente web para recoger los datos. 98 00:07:40,519 --> 00:07:55,759 Esto para situarnos y aterrizar en el concepto flujo de datos, comunicar nuestra aplicación con el exterior y a la hora de organizarlos, seguimos un poco también analizándolo aquí en este esquema, tenemos dos alternativas. 99 00:07:55,759 --> 00:08:04,860 Por un lado, los que tienen que ver con stream, que tenemos aquí input lectura de streams y por aquí output salida de streams. 100 00:08:06,160 --> 00:08:20,420 Y luego tenemos otro bloque que son los que tenemos por aquí abajo, que sería el reader, este reader sería el equivalente, digamos, a este nivel del input stream y el writer sería el equivalente del output stream. 101 00:08:20,420 --> 00:08:25,540 ¿En qué se diferencia InputStream, OutputStream de Reader y Writer? 102 00:08:26,959 --> 00:08:31,860 Mira, cuando estamos hablando de streams, tanto para el Input como para el Output, 103 00:08:32,360 --> 00:08:35,759 se considera que el intercambio que se realiza a través del flujo, 104 00:08:35,980 --> 00:08:40,299 bien sea con cualquiera de todos los posibles flujos de los que hemos hablado antes, 105 00:08:40,919 --> 00:08:48,240 se hace byte a byte, es decir, se cogen grupos de 8 bits y se transfieren a través del flujo. 106 00:08:48,240 --> 00:08:57,419 Si estamos leyendo un fichero, pues leemos 8 bits, nos da igual lo que sea. Si estamos escribiendo, pues escribimos 8 bits, nos da igual lo que sea. 107 00:08:57,559 --> 00:09:03,460 Que estamos comunicando una aplicación con otra a través de un socket, enviamos 8 bits y el otro lee 8 bits. 108 00:09:04,200 --> 00:09:10,840 Digamos que sin preocuparnos el uso que luego dentro de la aplicación está teniendo esa información. 109 00:09:10,840 --> 00:09:19,110 Vale, pues esto es lo que sucede con los streams 110 00:09:19,110 --> 00:09:25,110 Si damos un pasito más allá, resulta que puede ser que a estos bits 111 00:09:25,110 --> 00:09:27,769 Bueno, imaginaos por ejemplo en este caso de streams 112 00:09:27,769 --> 00:09:31,529 Un caso en el que no tendríamos que ir mucho más allá 113 00:09:31,529 --> 00:09:34,309 Pues pensad que lo que estamos cogiendo es una imagen 114 00:09:34,309 --> 00:09:38,129 Entonces tenemos un ficherito JPG con una imagen 115 00:09:38,129 --> 00:09:42,129 que no está construido a base de palabras 116 00:09:42,129 --> 00:09:45,450 o de textos, sino que directamente los píxeles luego 117 00:09:45,450 --> 00:09:49,929 van a ir cogiendo colores y tonos en esos colores 118 00:09:49,929 --> 00:09:54,129 en base a la información que tenga bit a bit cada uno de los datos que van 119 00:09:54,129 --> 00:09:57,909 llegando. Se irán agrupando luego para esto. Si vamos a transmitir una 120 00:09:57,909 --> 00:10:02,029 imagen de un ordenador a otro, podríamos hacerla directamente a través 121 00:10:02,029 --> 00:10:05,990 de un stream. Pero puede ser que esa información 122 00:10:05,990 --> 00:10:11,029 la queremos guardar en ficheros que estén, digamos, codificados a nivel de carácter. 123 00:10:11,269 --> 00:10:16,309 Muy habitual que guardemos un fichero con información, pues no sé, una carta que queremos escribir. 124 00:10:16,990 --> 00:10:22,809 Hola amigo, ¿cómo estás? Espero que hayas pasado un buen puente, nos vemos en unos días. 125 00:10:23,509 --> 00:10:27,590 Pues esta información es verdad que la podemos guardar byte a byte, 126 00:10:27,730 --> 00:10:30,610 porque no dejan de ser conjuntos de bits cada una de las letras, 127 00:10:30,610 --> 00:10:34,669 pero igual queremos guardarlo, digamos, dando un salto 128 00:10:34,669 --> 00:10:38,730 conceptual más alto y haciendo una encapsulación de esos bits para que 129 00:10:38,730 --> 00:10:42,690 tengan ya un cierto tratamiento como caracteres, es decir, le damos cierto 130 00:10:42,690 --> 00:10:46,509 sentido ya a los bits para que luego sea más fácil su trabajo 131 00:10:46,509 --> 00:10:50,750 entonces eso, en lugar de hacerlo con streams, lo hacemos 132 00:10:50,750 --> 00:10:54,730 a través de estas otras clases, que ya en lugar de guardar byte 133 00:10:54,730 --> 00:10:58,669 a byte como agrupaciones de 8 bits, ya guardan 16 134 00:10:58,669 --> 00:11:05,149 bits y lo guardan en formato de carácter y con estos hacemos lectura ya en formato de carácter 135 00:11:05,149 --> 00:11:11,309 y con los writers enviamos o guardamos en un fichero información a nivel de carácter. Ahora 136 00:11:11,309 --> 00:11:17,570 vemos también cómo vamos trabajando con ello. Entonces, primer concepto, flujos. Segundo 137 00:11:17,570 --> 00:11:25,970 concepto, diferenciar entre streams y los que tienen este otro criterio ya de carácter, 138 00:11:25,970 --> 00:11:42,590 Es decir, le damos cierto sentido a esos datos que se están transmitiendo por los flujos. Y luego hay otro concepto, bueno aquí hay muchas clases que no vamos a ver todas, vamos a trabajar sobre algunas de ellas, pero otro concepto que también es interesante es el de Buffered. 139 00:11:42,590 --> 00:11:57,059 Fijaros, por aquí tenemos un BufferedInputStream, por aquí tenemos un BufferedOutputStream y por aquí debemos tener un Buffered, algún otro Buffered también. 140 00:12:00,200 --> 00:12:03,059 Aquí, BufferedReader, por aquí, estaba buscando este tercero. 141 00:12:03,759 --> 00:12:10,019 ¿Qué sucede cuando hacemos accesos con clases que no manejan el Buffer? 142 00:12:10,759 --> 00:12:15,059 Pues se entiende que cada una de las lecturas o escriteras que hagamos, por ejemplo, en un fichero, 143 00:12:15,059 --> 00:12:22,120 que es uno de los modelos de flujos de datos, se hace, si es un string byte a byte, 144 00:12:22,279 --> 00:12:24,960 entonces cada vez que hagamos una lectura se irá al disco, 145 00:12:25,039 --> 00:12:29,919 imaginaos que ese fichero está en un pendrive, se irá al disco, cogerá ese byte y nos lo dará. 146 00:12:30,460 --> 00:12:34,600 Si hacemos una segunda lectura en nuestro programa que tenemos un bucle de lectura de byte a byte, 147 00:12:34,759 --> 00:12:37,419 pues se volverá a ir al disco y lo leerá. 148 00:12:37,580 --> 00:12:39,980 Una tercera se irá al disco y lo leerá. 149 00:12:40,019 --> 00:12:54,120 Y para la escritura igual, pues uno a uno irá haciendo escrituras en disco. Los accesos a disco en principio, bueno, pues es algo que para la eficiencia de los programas es razonablemente costoso para los programas. 150 00:12:54,120 --> 00:13:20,720 Entonces si buscamos eficiencia lo que podemos hacer es utilizar clases que trabajan con buffers. Estos buffers son espacios de memoria intermedia, normalmente a nivel de hardware se almacenan en trocitos de RAM, en los cuales cuando hacemos el acceso a disco para lectura se trae mucha información de un golpe, con lo cual los accesos a disco son menos costosos y los agrupan todos en memoria RAM. 151 00:13:20,720 --> 00:13:40,960 Y ya el programa, en lugar de irse al disco, leerá desde memoria RAM esos datos, con lo cual se gana eficiencia al tener los buffers y además se facilita la posibilidad de leer grupos de datos a la hora de coger los orders del buffer y no estarlos cogiendo desde el disco. 152 00:13:40,960 --> 00:13:51,460 entonces imaginaos que queremos hacer una lectura de información con un determinado formato 153 00:13:51,460 --> 00:13:56,259 y que tenga ese formato ya esté basado en caracteres 154 00:13:56,259 --> 00:14:03,440 pues que podríamos hacer, podríamos perfectamente iniciar la conexión a través de un input stream 155 00:14:03,440 --> 00:14:10,320 vamos a hacer una conexión a un fichero como para recoger bytes 156 00:14:10,320 --> 00:14:13,539 pero en lugar de manejarlos en el programa como stream 157 00:14:13,539 --> 00:14:15,980 este inputStream podemos venirnos por aquí 158 00:14:15,980 --> 00:14:19,799 por ejemplo encasularlo en un inputStreamReader 159 00:14:19,799 --> 00:14:22,320 que lo que hace es convertir un stream a un reader 160 00:14:22,320 --> 00:14:24,679 es decir, le da ese cierto formato a carácter 161 00:14:24,679 --> 00:14:28,200 y luego este inputStreamReader podríamos decir que 162 00:14:28,200 --> 00:14:30,960 lo vamos a terminar en realidad desde la aplicación 163 00:14:30,960 --> 00:14:32,740 leyéndolo con un buffer a reader 164 00:14:32,740 --> 00:14:35,320 es decir, le vamos metiendo diferentes capas 165 00:14:35,320 --> 00:14:39,139 y desde el programa podemos leer a nivel de carácter 166 00:14:39,139 --> 00:14:46,220 desde un buffer habiendo hecho toda esta conversión de información ahora lo vamos 167 00:14:46,220 --> 00:14:51,919 viendo en los programas entonces vamos mirar vamos a irnos al código y empezamos a hacer 168 00:14:51,919 --> 00:15:35,679 cosas ya de todo esto una vez hecha esta pequeña introducción unimos eclipse por aquí se lo piensa 169 00:15:35,679 --> 00:16:03,539 un poquito vamos a crear un proyecto quería elegir todo algo más se me ha quedado en el 170 00:16:03,539 --> 00:16:49,940 nombre del proyecto tema 10 vamos a crear el método de inicio mira lo primero que vamos a 171 00:16:49,940 --> 00:16:56,960 hacer si os parece para empezar a trabajar es pensando en input string lectura de carácter 172 00:16:56,960 --> 00:17:03,059 a carácter el primer flujo que tenemos que funciona ya bajo este modelo es el system 173 00:17:03,059 --> 00:17:09,059 in que ya lo conocemos de haber trabajado con él otras veces para leer información desde teclado 174 00:17:10,500 --> 00:17:16,900 entonces fijaros podríamos y decir si ponemos aquí system acordaros que normalmente ahora 175 00:17:16,900 --> 00:17:20,539 después lo hacemos también. System.in lo que hacíamos era con Scanner, 176 00:17:21,000 --> 00:17:25,039 creábamos un objeto de la clase Scanner y en el constructor de la clase Scanner 177 00:17:25,039 --> 00:17:29,500 decíamos que en casule, es decir, le ponga una capa como si fuese una cebolla 178 00:17:29,500 --> 00:17:33,019 y el System.in fuera el corazón de la cebolla, le poníamos una capa por encima 179 00:17:33,019 --> 00:17:38,359 de otra clase que tenemos definida en las librerías de Java que es la clase Scanner. 180 00:17:39,180 --> 00:17:43,900 ¿Qué pasa con la clase Scanner? Pues que permite trabajar a nivel de carácter 181 00:17:43,900 --> 00:17:46,740 y además con información metida 182 00:17:46,740 --> 00:17:49,799 como en buffers, como decíamos, como las buffers 183 00:17:49,799 --> 00:17:51,519 de las que hemos hablado antes. 184 00:17:52,819 --> 00:17:55,819 Para nuestra comodidad en el programa, encasulábamos 185 00:17:55,819 --> 00:17:57,980 el SystemIn dentro de Scanner, ahora después lo hacemos 186 00:17:57,980 --> 00:18:01,059 nuevamente, pero SystemIn ya de hecho 187 00:18:01,059 --> 00:18:04,799 realiza una conexión de un flujo 188 00:18:05,440 --> 00:18:07,859 pero bajo el modelo de InputStream. 189 00:18:09,299 --> 00:18:10,400 Entonces si cogemos y decimos 190 00:18:10,400 --> 00:18:19,079 SystemIn.SystemIn 191 00:18:19,180 --> 00:18:25,720 punto en punto fijaros como ya nos ofrece realmente existen cosas que hacer y una de 192 00:18:25,720 --> 00:18:32,759 las cosas que tenemos es aquí un rit pues esto lo que nos están haciendo es una lectura de 193 00:18:32,759 --> 00:18:40,259 información a través de un flujo byte a byte y fijaros que nos permite hacer una lectura que 194 00:18:40,259 --> 00:18:47,640 nos devuelve un entero vale un entero que cogerá la información de un byte o incluso podemos indicar 195 00:18:47,640 --> 00:18:51,380 aquí que tenga como parámetro 196 00:18:51,380 --> 00:18:54,200 un array de bytes, vamos a hacer las dos cosas 197 00:18:54,200 --> 00:19:02,380 decimos int y valor, definimos una 198 00:19:02,380 --> 00:19:08,309 variable por aquí, system int a quien está asociado, recordad que 199 00:19:08,309 --> 00:19:12,630 es el flujo de datos que tenemos asociado a la lectura de teclado 200 00:19:12,630 --> 00:19:15,950 y como es un input string 201 00:19:15,950 --> 00:19:26,259 ofrece el método read, nos dice que lo metamos dentro de un try catch 202 00:19:26,259 --> 00:19:29,400 para capturar excepciones de errores que se puedan producir 203 00:19:29,400 --> 00:19:35,119 y ahora si hacemos aquí un system.out.println 204 00:19:35,119 --> 00:19:40,140 tened en cuenta que aquí, system.out 205 00:19:40,140 --> 00:19:43,900 es otro flujo de datos, según estamos hablando, en este caso 206 00:19:43,900 --> 00:19:49,099 comunica nuestro programa con formato de salida hacia la pantalla 207 00:19:49,099 --> 00:19:52,579 salida estándar, la pantalla, y system.out 208 00:19:52,579 --> 00:19:56,279 si system.in está basado en 209 00:19:56,279 --> 00:20:00,180 un InputStream, si está en Auth, está basado en un PrintStream 210 00:20:00,180 --> 00:20:05,650 que tendrá, es una clase que está ahí en Java, fijaros esta 211 00:20:05,650 --> 00:20:09,829 jerarquía de clases, de la clase Auth, está la clase 212 00:20:09,829 --> 00:20:12,450 InputStream, que es una clase abstracta, de la cual 213 00:20:12,450 --> 00:20:17,630 o es una interfaz, no sé, muy bien, qué significa esto 214 00:20:17,630 --> 00:20:21,630 y por aquí tenemos otras clases que van heredando de estas anteriores 215 00:20:21,630 --> 00:20:26,980 Pues OutputStream es un PrintStream, también es un flujo de datos 216 00:20:26,980 --> 00:20:29,259 una forma de gestionar flujos de datos 217 00:20:29,259 --> 00:21:20,400 Ese flujo de datos tiene un método implementado que es el println, entonces si aquí ponemos que nos muestre y valor, vamos a poner aquí un system.out.println, volvemos a utilizar ese flujo de datos, dime un carácter, entonces si ejecutamos por aquí, me dice que lo mantenga inicializado aunque lo vamos a sobreescribir aquí el valor, 218 00:21:20,400 --> 00:21:24,940 dice, dime un carácter, digo una D 219 00:21:24,940 --> 00:21:28,920 y fijaros, me muestra un 100, 100 que es, pues es un valor 220 00:21:28,920 --> 00:21:33,099 de un entero, es un byte, si aquí le hacemos un casting a un char 221 00:21:33,099 --> 00:21:38,470 a ver, ese es el valor ASCII de la D que he puesto en este 222 00:21:38,470 --> 00:21:42,109 momento, si yo cojo y digo aquí D, ahora ya me dice D, porque 223 00:21:42,109 --> 00:21:44,869 del valor 100 he hecho un casting y me lo ha convertido a un char 224 00:21:44,869 --> 00:21:48,710 si no, pues directamente me muestra el valor de 225 00:21:48,710 --> 00:21:53,450 sin preocuparse de formato ni nada el valor de un byte 226 00:21:53,450 --> 00:21:57,509 un byte que está guardado en este caso en un entero, pues es lo que me muestra 227 00:21:57,509 --> 00:22:07,730 con el 100, voy a poner los dos, veis, D 228 00:22:07,730 --> 00:22:12,029 el 100, aquí me muestra este 100 y este D, si yo hago una ejecución y pongo 229 00:22:12,029 --> 00:22:16,230 D A, en realidad aquí se va a quedar un poco bloqueado 230 00:22:16,230 --> 00:22:19,730 el input hasta que le meta un enter, pero si le doy un enter 231 00:22:19,730 --> 00:22:23,369 fijaros como lo que me muestra es un único carácter, este la D 232 00:22:23,369 --> 00:22:25,049 el de la A no me ha mostrado nada 233 00:22:25,049 --> 00:22:26,269 si yo pongo 234 00:22:26,269 --> 00:22:33,799 dos ahora y ejecuto 235 00:22:33,799 --> 00:22:35,440 dos, pues si pongo 236 00:22:35,440 --> 00:22:37,539 de A, pues me leerá el primero 237 00:22:37,539 --> 00:22:41,349 con el 100, bueno me ha mostrado 238 00:22:41,349 --> 00:22:43,089 dos veces porque no he vuelto a hacer lectura 239 00:22:43,089 --> 00:22:49,740 voy a meterlo aquí 240 00:22:49,740 --> 00:22:51,500 dentro del try catch 241 00:22:51,500 --> 00:23:01,650 sí, pero como 242 00:23:01,650 --> 00:23:03,710 el método read 243 00:23:03,710 --> 00:23:05,970 lee un solo byte, pues no ha leído más 244 00:23:05,970 --> 00:23:07,609 ahora hacemos que lea 245 00:23:07,609 --> 00:23:08,529 todos los que haya 246 00:23:08,529 --> 00:23:11,849 en este caso lo que ha pasado es que había hecho un solo read 247 00:23:11,849 --> 00:23:16,349 pues entonces ha leído un byte, este método lee un byte 248 00:23:16,349 --> 00:23:19,809 y el primer byte era la D, pues ya está, esto es lo que ha leído 249 00:23:19,809 --> 00:23:24,210 la A, bueno pues si hacemos una segunda lectura del system in read 250 00:23:24,210 --> 00:23:28,009 pues leerá la A, mirad ahora he puesto dos read aquí 251 00:23:28,009 --> 00:23:32,529 cogemos, a ver, lo salvo por aquí 252 00:23:32,529 --> 00:23:38,240 si pongo D A, pues ahora ya me dice 253 00:23:38,240 --> 00:23:46,339 he leído el primero con un 100 y el segundo con un 97, que después de hacer el casting me dice que es una D y que es una A. 254 00:23:48,400 --> 00:23:58,859 Aquí, si no recuerdo mal, existe el método SystemInAvailable que indica mientras haya información disponible para lectura. 255 00:23:58,859 --> 00:24:29,559 Entonces aquí podríamos poner while mientras haya información disponible para la lectura. Bueno, pues hazme, mientras haya información para la lectura, a ver aquí qué es lo que le pasa. Vale, a bailable. Esto debe devolver, a ver, ¿qué devuelve? 256 00:24:29,559 --> 00:24:34,740 no debo devolver un boolean 257 00:24:34,740 --> 00:24:38,839 y por eso se me queja, mira devuelve un entero 258 00:24:38,839 --> 00:24:41,000 entonces 259 00:24:41,000 --> 00:24:46,339 para que poderlo meter dentro de un while o dentro de un if habrá que decir 260 00:24:46,339 --> 00:24:49,640 algo así que se evalúe, vamos a probar 261 00:24:49,640 --> 00:24:53,000 entonces ahora cogemos y decimos da 262 00:24:53,000 --> 00:25:00,279 aquí, o menos uno, puede ser 263 00:25:00,279 --> 00:25:29,029 puede ser así. Bueno, pues aquí lo tenéis como, bueno, con el menos uno validando el final del 264 00:25:29,029 --> 00:25:36,690 flujo, pues nos lee tantos caracteres, pero fijaros que estará en el bucle tantas veces como caracteres 265 00:25:36,690 --> 00:25:43,789 haya si utilizamos el método read. También el system.in nos permite leer un array. Vamos a hacerlo 266 00:25:43,789 --> 00:25:51,390 con un array. Decimos, ¿un array de qué? Pues fijaros que es un stream, es un input stream, entonces es 267 00:25:51,390 --> 00:26:00,299 un array de bytes. De hecho, en lugar de int, aquí podríamos poner, yo creo, byte. Vamos a ver si nos 268 00:26:00,299 --> 00:26:28,039 deja byteR. Vamos a hacer una lectura de un array. Vamos a darle un tamaño. Yo creo que si no, no va a 269 00:26:28,039 --> 00:26:35,119 fallar. Aunque no utilicemos luego todo el array para los caracteres que le damos. Vamos a darle, 270 00:26:35,220 --> 00:26:47,930 por ejemplo, un tamaño de 20. Y ahora podríamos poner aquí system.inread. Y en lugar de utilizar 271 00:26:47,930 --> 00:26:51,369 este método que nos devolvió un entero, vamos a utilizar este otro 272 00:26:51,369 --> 00:26:55,849 que lo que lee se lo guarda en el array que pongamos aquí 273 00:26:55,849 --> 00:26:59,630 y aquí lo que nos devuelve es el número de caracteres que se han leído 274 00:26:59,630 --> 00:27:03,529 entonces hacemos aquí un read, indicamos que queremos que guarde la información 275 00:27:03,529 --> 00:27:10,740 en varray y aquí podemos poner un int 276 00:27:10,740 --> 00:27:13,720 y num 277 00:27:13,720 --> 00:27:27,440 num vice leídos, lo metemos en el try catch 278 00:27:27,440 --> 00:27:33,859 entonces esto lo que se entiende es que para este array tenemos un espacio 279 00:27:33,859 --> 00:27:37,940 de 20 ¿verdad? entonces no podríamos meter más de 20 bytes en la 280 00:27:37,940 --> 00:27:42,039 lectura pero hasta 20 pues sí, con este system.ir este otro método 281 00:27:42,039 --> 00:27:46,180 lo que hará será leer los que, los caracteres 282 00:27:46,180 --> 00:27:49,960 que haya pendientes de leer, será algo parecido a este while en el cual leíamos 283 00:27:49,960 --> 00:27:54,140 uno a uno, lo único que leerá todos de golpe, y ahora para recorrer 284 00:27:54,140 --> 00:27:56,299 todos los arrays que tenga el byte 285 00:27:56,299 --> 00:27:59,539 pues cogeríamos y haríamos un while 286 00:27:59,539 --> 00:28:03,140 mientras, o un for 287 00:28:03,140 --> 00:28:08,299 vamos a hacerlo con un for, for, mientras int 288 00:28:08,299 --> 00:28:11,619 i sea igual a cero hasta que i 289 00:28:11,619 --> 00:28:15,480 sea menor que el número de bytes leídos 290 00:28:15,480 --> 00:28:24,980 hacemos un i++, y en cada uno de estos que estamos leyendo 291 00:28:24,980 --> 00:28:28,980 pues lo podemos mostrar por pantalla, entonces la información la tenemos en el array 292 00:28:28,980 --> 00:28:34,319 podemos hacer un system.auth.println 293 00:28:34,319 --> 00:28:38,670 de la posición i 294 00:28:38,670 --> 00:28:44,230 y si queréis podríamos hacer también esto mismo 295 00:28:44,230 --> 00:28:45,970 pero haciéndole un casting a un char 296 00:28:45,970 --> 00:28:47,990 para que se parezca al ejercicio que hacíamos antes 297 00:28:47,990 --> 00:28:49,349 cuando leíamos de uno en uno 298 00:28:49,349 --> 00:28:55,599 bueno, a este no le gusta esto 299 00:28:55,599 --> 00:28:58,240 fijaros, el motivo es que este está definido 300 00:28:58,240 --> 00:29:02,019 esta variable está definida dentro del ámbito del try 301 00:29:02,019 --> 00:29:04,539 con lo cual es una variable local a este ámbito 302 00:29:04,539 --> 00:29:06,720 y estamos intentando utilizarla aquí 303 00:29:06,720 --> 00:29:10,599 dice no existe esta variable, pues lo que podemos hacer es definirla 304 00:29:10,599 --> 00:29:17,400 aquí fuera y aquí usarla, entonces como ya ahora 305 00:29:17,400 --> 00:29:21,400 ya está aquí, está definida en este ámbito, con lo cual está tanto disponible aquí 306 00:29:21,400 --> 00:29:27,549 como aquí, y ahora por ejemplo metemos aquí abc 307 00:29:27,549 --> 00:29:32,910 y fijaros como, bueno ponle los tres, el número de caracteres leídos 308 00:29:32,910 --> 00:29:36,509 hace el for hasta tres veces, porque se habrá cargado aquí 309 00:29:36,509 --> 00:29:40,009 porque hemos leído tres bytes y se trabaja con ello 310 00:29:40,009 --> 00:29:45,950 fijaros que podemos perfectamente aunque sean caracteres leerlos como a raíz de bytes y luego 311 00:29:45,950 --> 00:29:50,750 hacer las gestiones que vayan tocando para trabajar con ellos como caracteres vale podríamos 312 00:29:50,750 --> 00:29:57,309 pero si queremos despreocuparnos de hacer esto porque sabemos que van a ser caracteres y queremos 313 00:29:57,309 --> 00:30:02,730 ya que tenga ese formato que podemos hacer con el sistema pues mira fijaros podríamos y hacer 314 00:30:02,730 --> 00:30:08,630 lo que venimos haciendo desde hace bastante tiempo para no trabajar con bytes con enteros 315 00:30:08,630 --> 00:30:12,690 o con bytes, en realidad esta lectura está leyendo 316 00:30:12,690 --> 00:30:16,410 byte a byte, aunque lo estamos metiendo en una variable numérica de mayor 317 00:30:16,410 --> 00:30:20,670 espacio de memoria RAM, pero está haciendo la lectura con cada uno de los reads 318 00:30:20,670 --> 00:30:24,150 o en este caso, leyendo cada uno de los bytes en un array 319 00:30:24,150 --> 00:30:28,049 en lugar de trabajar con bytes, podemos querer trabajar directamente con 320 00:30:28,049 --> 00:30:31,609 strings, entonces, ¿qué era lo que hacíamos? 321 00:30:32,009 --> 00:30:36,349 con el system.in para que nos resultase más fácil, pues decíamos, es cierto que sabemos 322 00:30:36,349 --> 00:30:46,630 que System.in es un flujo de datos tipo string, pero vamos a utilizar clases que tengamos en la 323 00:30:46,630 --> 00:30:52,869 librería de Java que nos faciliten la vida para trabajar cuando estemos considerando lecturas 324 00:30:52,869 --> 00:30:58,329 desde teclado que sean caracteres. Entonces, ¿qué hacíamos durante el curso? Nos hemos ido a la 325 00:30:58,329 --> 00:31:01,049 clase Scanner, que la tenemos en las librerías de Java, 326 00:31:02,509 --> 00:31:06,609 New, Scanner, y decíamos 327 00:31:06,609 --> 00:31:10,470 a Scanner vamos a encasular 328 00:31:10,470 --> 00:31:14,430 con un objeto de la clase Scanner que un inputString 329 00:31:14,430 --> 00:31:18,329 que es la lectura de teclado. Ahora después también podremos 330 00:31:18,329 --> 00:31:22,349 coger, y aquí en lugar de poner que el inputString sea la lectura de teclado, 331 00:31:22,490 --> 00:31:25,170 podremos poner que sea un fichero. Después lo hacemos. 332 00:31:25,170 --> 00:31:29,329 ¿Y cómo trabajaremos? Pues trabajaremos con los métodos que tiene 333 00:31:29,329 --> 00:31:33,589 Scanner a través de este objeto en su librería de definidas, en este caso 334 00:31:33,589 --> 00:31:37,490 para leer un fichero, que es un inputString, un flujo de datos de entrada 335 00:31:37,490 --> 00:31:41,410 al programa byte a byte, y en este caso un inputString que era 336 00:31:41,410 --> 00:31:45,470 un flujo de bytes que tenemos de entrada al programa, pero desde 337 00:31:45,470 --> 00:31:49,630 teclado. Es decir, Scanner puede encasular cualquier 338 00:31:49,630 --> 00:31:53,670 flujo de entrada, cualquier inputString que tengamos 339 00:31:53,670 --> 00:31:57,309 aquí, lo importamos, y bueno, aquí no voy a hacer 340 00:31:57,309 --> 00:32:03,309 nada nuevo, y fijaros como aquí ya somos capaces de 341 00:32:03,309 --> 00:32:07,150 hacer un myscan, punto, 342 00:32:15,400 --> 00:32:18,759 y hacemos un net, un netline, con un netline que nos devuelve, nos devuelve 343 00:32:18,759 --> 00:32:22,720 una stream, ¿verdad? Systeming devuelve streams, no, sabemos que 344 00:32:22,720 --> 00:32:25,680 devuelve bytes, pero como lo hemos encasulado con 345 00:32:25,680 --> 00:32:30,880 una variable tipo scanner, pues conseguimos hacer esa transformación, 346 00:32:31,000 --> 00:32:32,380 nos resulta muy cómodo en el programa. 347 00:32:32,819 --> 00:33:00,920 y aquí podemos mostrar la información. Ya está, fijaros 348 00:33:00,920 --> 00:33:05,099 como directamente hemos cogido un string que en este programa trabajamos con 349 00:33:05,099 --> 00:33:09,140 string directamente y aunque vamos a leer desde teclado, en lugar de coger las cosas 350 00:33:09,140 --> 00:33:13,339 metiéndolo en un array de bytes y haciendo transformaciones, construyendo 351 00:33:13,339 --> 00:33:17,740 un string a partir de cada uno de los caracteres 352 00:33:17,740 --> 00:33:21,160 aquí con posibles bucles que vayamos 353 00:33:21,160 --> 00:33:25,339 haciendo, que podríamos construirlo a partir de esto ciertamente, leyendo bytes 354 00:33:25,339 --> 00:33:28,099 pues aquí eso mismo digamos que estará haciendo 355 00:33:28,099 --> 00:33:31,339 Scanner por detrás por nosotros y nos dice 356 00:33:31,339 --> 00:33:34,119 pues para que tu programa quede más clarito y tú lo entiendas mejor 357 00:33:34,119 --> 00:33:36,839 y te cueste menos el hacer el desarrollo, tú haz un 358 00:33:36,839 --> 00:33:39,980 Sline que te voy a devolver un String, aunque estemos leyendo desde 359 00:33:39,980 --> 00:33:41,779 un flujo de datos de 360 00:33:41,779 --> 00:33:46,119 caracteres. Bueno, Scanner lo conocemos 361 00:33:46,119 --> 00:33:48,980 desde hace tiempo, pero ahora bueno ya le damos un poco 362 00:33:48,980 --> 00:33:51,819 más sentido a este Sistening que poníamos 363 00:33:51,819 --> 00:33:54,920 desde el principio, que decíamos es para leer desde el teclado 364 00:33:54,920 --> 00:34:11,010 pero cómo funciona eso. Fijaros, si System.in es un InputStream, hemos visto que podemos leer directamente desde este, pero todos estos pueden trabajar como InputStreams en realidad. 365 00:34:12,289 --> 00:34:23,050 Hay clases especializadas dependiendo de la naturaleza de cada uno de los flujos de datos de los que vayamos leyendo. Entonces, por ejemplo, tenemos el FileInputStream para leer como un InputStream, 366 00:34:23,050 --> 00:34:49,949 pero desde un fichero, bueno pues tiene cierta especialidad, está de alguna forma un poco especializado con aparte de las clases que tenga el input stream de los métodos pues tendrá el file input stream propios que nos facilitarán la vida para esto, por ejemplo a lo mejor el constructor del objeto de file input stream, ahora después hacemos uno pues tendrá la posibilidad de indicar del fichero de la ruta donde está el fichero desde el que queremos leer. 367 00:34:49,949 --> 00:34:56,340 este input string, pues podemos querer y trabajar con él en lugar de 368 00:34:56,340 --> 00:35:00,300 haciendo lecturas de bytes, byte a byte, pues podemos querer trabajar 369 00:35:00,300 --> 00:35:04,260 con él con cierto formato ya dado. Hemos visto 370 00:35:04,260 --> 00:35:07,900 una posibilidad que tenemos para el system in, que es con la clase scanner 371 00:35:07,900 --> 00:35:12,300 que queda fuera de esta parte de la estructura de clases 372 00:35:12,300 --> 00:35:16,340 de Java, estará por ahí en otro sitio definida, pero dentro de esta 373 00:35:16,340 --> 00:35:20,380 estructura podríamos ese input string, trabajarlo como un reader 374 00:35:20,380 --> 00:35:26,519 que ya nos da cierto formato. Entonces, ¿cómo podemos convertir 375 00:35:26,519 --> 00:35:30,260 un stream en algo que sea un reader? Pues si nos fijáis por aquí, 376 00:35:30,400 --> 00:35:34,440 los nombres nos suelen dar ideas y tenemos esta que dice 377 00:35:34,440 --> 00:35:38,619 input de entrada, conviérteme un stream a un reader, es decir, 378 00:35:38,679 --> 00:35:44,360 da cierto formato ya a los caracteres. Entonces, nos venimos por aquí 379 00:35:44,360 --> 00:35:56,440 y decimos, System.im es un input stream. En este programa, 380 00:35:56,440 --> 00:36:00,599 en particular puede ser que en lugar de trabajar con byte me interese trabajar con caracteres 381 00:36:00,599 --> 00:36:04,860 pues bueno, una forma típica de empezar a hacer esa conversión 382 00:36:04,860 --> 00:36:08,159 es decir, ese input, el stream lo voy a convertir a un reader 383 00:36:08,159 --> 00:36:12,239 entonces cojo por aquí y empiezo a encapsular esa información 384 00:36:12,239 --> 00:36:15,480 igual que antes he encapsulado con scanner, pues ahora la digo aquí 385 00:36:15,480 --> 00:36:21,820 input stream reader 386 00:36:21,820 --> 00:36:27,730 y sr, vamos a llamarlo 387 00:36:27,730 --> 00:36:30,510 de inputStreamReader igual a new 388 00:36:30,510 --> 00:36:35,469 inputStreamReader 389 00:36:35,469 --> 00:36:39,349 Estoy creando un objeto de esta clase 390 00:36:39,349 --> 00:36:47,650 que es esta que tenemos aquí. Y a este 391 00:36:47,650 --> 00:36:51,510 constructor, la idea que tiene esta clase 392 00:36:51,510 --> 00:36:57,320 definida en la librería de Java es que un stream de entrada 393 00:36:57,320 --> 00:37:01,380 lo convierte a un reader de entrada 394 00:37:01,380 --> 00:37:10,019 Es decir, los bytes que tenemos desde el stream le va a dar cierto formato ya para leerlos de 16 en 16 bits y darle cierto formato de carácter. 395 00:37:11,019 --> 00:37:15,480 Y le indicamos el stream que queremos convertir a reader en el constructor. 396 00:37:15,940 --> 00:37:19,980 Entonces aquí podemos poner un input stream que, por ejemplo, podría ser el system. 397 00:37:20,599 --> 00:37:26,619 Vamos a cargar las clases desde Java.io. 398 00:37:28,300 --> 00:37:33,000 Y esto lo que hará será esa conversión leyendo desde este stream. 399 00:37:33,000 --> 00:37:36,639 pero otra cosa que hemos dicho que nos puede resultar interesante 400 00:37:36,639 --> 00:37:39,199 es trabajar con información 401 00:37:39,199 --> 00:37:42,920 leída desde el dispositivo, en este caso desde el teclado 402 00:37:42,920 --> 00:37:45,500 en un buffer, entonces tenemos 403 00:37:45,500 --> 00:37:48,460 la posibilidad de cargarlo en un buffer reader, ahora ya tenemos 404 00:37:48,460 --> 00:37:51,059 un reader y queremos meterle un buffer 405 00:37:51,059 --> 00:37:59,849 fijaros que como salida, esto ya es 406 00:37:59,849 --> 00:38:01,750 un reader porque hemos hecho esa conversión 407 00:38:01,750 --> 00:38:05,730 y de hecho, fijaros como 408 00:38:05,730 --> 00:38:08,469 me ofrece métodos para leer ya directamente 409 00:38:08,469 --> 00:38:12,130 directamente desde este reader 410 00:38:12,130 --> 00:38:14,849 podríamos leer ya, pero por darle 411 00:38:14,849 --> 00:38:18,369 por poner otra capita más a esa cebolla 412 00:38:18,369 --> 00:38:20,909 pues podríamos coger y decir voy a crear 413 00:38:20,909 --> 00:38:22,690 un objeto de la clase buffer reader 414 00:38:22,690 --> 00:38:25,929 que lo que hace es un reader 415 00:38:25,929 --> 00:38:29,610 recordad que esto en sí es un reader 416 00:38:29,610 --> 00:38:32,809 que hemos obtenido desde este stream 417 00:38:32,809 --> 00:38:46,679 y le indicamos el reader 418 00:38:46,679 --> 00:38:56,619 al cual le queremos aplicar un buffer. Y ahora aquí podemos 419 00:38:56,619 --> 00:39:00,179 escoger y hacer lecturas, fijaros como 420 00:39:00,179 --> 00:39:04,579 información ya de tipo string, igual que con el scanner hemos 421 00:39:04,579 --> 00:39:08,639 hecho lecturas de Nestline, pues aquí 422 00:39:08,639 --> 00:39:12,739 tenemos la posibilidad con el método read, nos da alternativas y entre ellas 423 00:39:12,739 --> 00:39:16,539 tenemos la de leer directamente una línea, es igual que 424 00:39:16,539 --> 00:39:20,539 este vendría a ser con otra clase de Java, el Nestline que 425 00:39:20,539 --> 00:39:46,360 tenemos con un objeto de la clase Scanner, desde el buffer ARRIVE. println br.redline 426 00:39:46,360 --> 00:40:01,260 Me pedirá un try-catch supongo. Vamos a poner un system.println aquí para pedir información. 427 00:40:01,260 --> 00:40:14,579 Dime algo. En este caso fijaros, estamos, hemos hecho tres aproximaciones al system.in, leerlo 428 00:40:14,579 --> 00:40:19,800 como un stream, leerlo como una cadena de caracteres con una clase que tenemos en la 429 00:40:19,800 --> 00:40:25,019 librería de java que la clase escáner y ahora vamos a leerlo desde una que está 430 00:40:25,019 --> 00:40:29,940 colgando esta estructura desde el stream hemos convertido en un reader con el 431 00:40:29,940 --> 00:40:34,019 input stream reader y ahora con el buffer reader vamos a leerlo apoyándonos en un 432 00:40:34,019 --> 00:40:39,679 buffer que hemos creado hacemos el read line y 433 00:40:39,679 --> 00:40:54,849 finalmente bueno ser lo que leamos lo sacamos por pantalla dime algo hola 434 00:40:54,849 --> 00:41:25,630 ¿Cómo estás? Bueno, pues ha hecho ahí todo el proceso, ha hecho la lectura, el readline, lo ha mostrado por pantalla, aquí lo tenéis. ¿Alguna duda? ¿Se entiende? Bueno, pues vamos a seguir trabajando con los streams, pero vamos a ir ahora a ficheros. 435 00:41:25,630 --> 00:41:34,719 acordaros que tenemos, en Eclipse estamos trabajando con el proyecto T 436 00:41:34,719 --> 00:41:38,920 y los proyectos, si no habéis cambiado el Workspace, la zona de trabajo, 437 00:41:40,019 --> 00:41:43,460 la máquina virtual que los pasé yo, vosotros donde lo tengáis, 438 00:41:44,340 --> 00:41:50,239 pues se van creando los proyectos en el Workspace. 439 00:41:54,719 --> 00:41:58,059 Fijaros, aquí tenemos un directorio por cada uno de todos estos, 440 00:41:58,059 --> 00:42:00,300 en particular este proyecto lo hemos llamado T, 441 00:42:00,300 --> 00:42:05,639 y este es el punto donde la ejecución 442 00:42:05,639 --> 00:42:09,599 desde Java busca la información, digamos es el punto raíz 443 00:42:09,599 --> 00:42:11,659 entonces si nosotros creamos aquí un fichero 444 00:42:11,659 --> 00:42:17,699 Nano es un editor de textos como del tipo del Notepad 445 00:42:17,699 --> 00:42:21,679 que suele estar incluido en distribuciones 446 00:42:21,679 --> 00:42:23,260 Linux, vamos a poner 447 00:42:23,260 --> 00:42:28,860 fichlet.txt, vamos a crear un fichero aquí que sea 448 00:42:28,860 --> 00:42:32,179 fichero LED de lectura, vamos a poner aquí 449 00:42:32,179 --> 00:42:40,530 un hola y nada, pues fijaros aquí lo tenemos 450 00:42:40,530 --> 00:42:43,070 ls, ya existe el fichero fichero LED, lo he puesto 451 00:42:43,070 --> 00:42:47,949 en el directorio RAID del proyecto 452 00:42:47,949 --> 00:42:51,989 aquí está el directorio src y bin, pues tal que por aquí 453 00:42:51,989 --> 00:42:59,480 y fijaros haciéndole en morg, que es un comando en linux, pues que te muestra 454 00:42:59,480 --> 00:43:03,519 el contenido, efectivamente tiene el hola este que hemos puesto como contenido 455 00:43:03,519 --> 00:43:06,960 cuando lo hemos editado, ahí está el fichero 456 00:43:06,960 --> 00:43:14,349 bueno, pues podemos hacer un poco la misma jugada, pero ahora para leer 457 00:43:14,349 --> 00:43:18,449 un ficherito, si queremos hacer la lectura 458 00:43:18,449 --> 00:43:22,630 directamente como streams, pues aquí lo que vamos a hacer va a ser 459 00:43:22,630 --> 00:43:25,889 venirnos a esta clase, bueno, pues que nos ayuda un poco a 460 00:43:25,889 --> 00:43:30,610 hacer el tratamiento como stream de ficheros, la file input 461 00:43:30,610 --> 00:43:41,500 stream, en lugar de leer de este flujo 462 00:43:41,500 --> 00:43:44,900 que era el teclado, pues ahora vamos a leer de otro flujo. 463 00:43:45,039 --> 00:43:49,519 Hemos dicho que los flujos son mecanismos que utilizamos para comunicar 464 00:43:49,519 --> 00:43:53,500 nuestro programa con el exterior. Un mecanismo es lectura de teclado, 465 00:43:53,619 --> 00:43:56,880 pues ahora vamos a utilizar otro que es lectura de ficheros. 466 00:43:56,880 --> 00:43:59,280 Entonces es File, InputStream, 467 00:43:59,860 --> 00:44:16,039 File, InputStream, vamos a llamarlo Fizz, y aquí en el constructor 468 00:44:16,039 --> 00:44:20,019 podemos indicar el nombre del fichero que queremos 469 00:44:20,019 --> 00:44:29,360 leer que era fitch led aquí pondríamos la ruta donde se encuentra el fichero como lo he creado 470 00:44:29,360 --> 00:44:37,500 justo en la en la ruta donde está el directorio en el directorio del proyecto en eclipse eclipse 471 00:44:37,500 --> 00:44:41,739 aquí donde empieza buscándolo si no habría que poner una ruta relativa absoluta para que terminara 472 00:44:41,739 --> 00:44:56,119 localizando el fichero pues la importamos por aquí hago el new por aquí vale y ahora esto me dirá que 473 00:44:56,119 --> 00:45:01,260 lo meta dentro un try catch por si no existiera el fichero poder capturar fijaros la excepción 474 00:45:01,260 --> 00:45:08,099 que captura file no phone excepción vale pues ahora aquí que tengo pues tengo un acceso a un 475 00:45:08,099 --> 00:45:14,500 flujo en este objeto que es en particular un fichero como puedo leerlo pues como un stream 476 00:45:14,500 --> 00:45:20,739 pues pongo aquí fix.read y fijaros que me permite igual que hacíamos con el system in antes la 477 00:45:20,739 --> 00:45:27,099 posibilidad de leer byte a byte esta información veis leerlo como enteros o releerlo como array 478 00:45:27,099 --> 00:45:33,940 de bytes vamos a hacer una jugada como la de antes la única diferencia en el programa es que 479 00:45:33,940 --> 00:45:39,179 ahora estamos indicando que el objeto fish es del tipo file input string y que lea de este 480 00:45:39,179 --> 00:45:46,440 sistema a diferencia de lo que hacíamos antes que lo que hacíamos era leer antes leíamos desde 481 00:45:46,440 --> 00:45:53,139 sistema ahora de fislet pero en realidad es un flujo conectado a mi programa en un lado de la 482 00:45:53,139 --> 00:46:00,659 tubería de ese flujo está pinchado en mi programa y estoy leyendo la información como streams entonces 483 00:46:00,659 --> 00:46:12,690 ahora voy a hacer una copia de estos dos estando variable la voy a poner por aquí y si hago que un 484 00:46:12,690 --> 00:46:28,000 rito aquí ahora de este le digo que me lo cargue por aquí añado la cláusula cats que tiene a este 485 00:46:28,000 --> 00:46:34,699 que tenga que ver con la lectura fijaros y o excepción y ahora aquí habré leído un carácter 486 00:46:34,699 --> 00:46:51,760 si yo pongo aquí un system.out.println de y valor a una ejecución y me dice 104 104 que será 487 00:46:51,760 --> 00:47:07,539 pues será el valor el valor así de probablemente de la h a ese valor como antes si le hago un 488 00:47:07,539 --> 00:47:12,579 casting para decir oye no me muestres el valor numérico muéstrame convierte ese valor numérico 489 00:47:12,579 --> 00:47:15,460 a un carácter, pues fijaros 490 00:47:15,460 --> 00:47:17,500 como ahora ya me dice efectivamente que es la H 491 00:47:17,500 --> 00:47:19,340 y si en lugar 492 00:47:19,340 --> 00:47:21,440 de leerlo con read, como hemos 493 00:47:21,440 --> 00:47:21,900 hecho aquí 494 00:47:21,900 --> 00:47:24,780 estoy repitiendo un poco 495 00:47:24,780 --> 00:47:27,179 los mismos pasos que habíamos hecho 496 00:47:27,179 --> 00:47:30,460 en la lectura anterior 497 00:47:30,460 --> 00:47:32,619 le paso un array de bytes 498 00:47:32,619 --> 00:47:34,880 pues cargará aquí todos los bytes que tiene 499 00:47:34,880 --> 00:47:37,000 la lectura y aquí el número de 500 00:47:37,000 --> 00:47:38,280 bytes que 501 00:47:38,280 --> 00:47:41,280 ha leído, que si es 502 00:47:41,280 --> 00:47:43,219 o en principio deberían ser cuatro. 503 00:47:44,659 --> 00:47:45,500 Hacemos aquí 504 00:47:45,500 --> 00:47:49,659 System.out.println 505 00:47:49,659 --> 00:47:58,449 byteleidos 506 00:47:58,449 --> 00:48:08,929 y valor 507 00:48:08,929 --> 00:48:11,869 y ahora voy a hacer copy-paste aquí 508 00:48:11,869 --> 00:48:13,690 y así perdemos menos tiempo 509 00:48:13,690 --> 00:48:15,849 del bucle este que había hecho aquí. 510 00:48:24,110 --> 00:48:25,849 Aquí en lugar de inum byteleidos 511 00:48:25,849 --> 00:48:27,710 que habíamos definido ahí abajo, lo hemos cargado 512 00:48:27,710 --> 00:48:29,429 el número de bytes aquí. 513 00:48:30,150 --> 00:48:30,829 Pues ahí lo tenemos. 514 00:48:31,809 --> 00:48:33,510 Entonces aquí lo que nos mostrará será 515 00:48:33,510 --> 00:48:37,710 cada uno de los caracteres, como lo hemos cargado en este caso 516 00:48:37,710 --> 00:48:41,489 con el read de un stream en un array de bytes 517 00:48:41,489 --> 00:48:45,369 pues nos mostrará uno a uno, nos mostrará la H, la O 518 00:48:45,369 --> 00:48:48,210 la L y la A, que es el contenido que tiene el fichero 519 00:48:48,210 --> 00:49:00,179 la H con su valor ASCII, ¿veis leídos? 520 00:49:01,940 --> 00:49:13,550 5104, curioso 521 00:49:13,550 --> 00:49:16,829 que me diga aquí 5104, no entiendo muy bien por qué 522 00:49:16,829 --> 00:49:20,369 porque luego en verdad el bucle si que lo hace aquí 523 00:49:20,369 --> 00:49:25,380 para los cuatro, bueno en cualquier caso ha leído la O 524 00:49:25,380 --> 00:49:28,320 la H, la O, la L y la A, es decir la información que teníamos 525 00:49:28,320 --> 00:49:33,860 en el fichero, por seguir dándole otra vuelta 526 00:49:33,860 --> 00:49:46,019 a esto, sobre todo para que veáis 527 00:49:46,019 --> 00:49:50,840 que bueno, que intentando 528 00:49:50,840 --> 00:49:54,039 buscar simplificarlo, en realidad luego no resulta 529 00:49:54,039 --> 00:49:56,219 muy complicado, esto 530 00:49:56,219 --> 00:49:59,260 simplificando el concepto 531 00:49:59,260 --> 00:50:02,340 vamos a coger el catch para que nos compile por aquí 532 00:50:02,440 --> 00:50:03,820 del try 533 00:50:03,820 --> 00:50:12,489 hacerlo así más rápido 534 00:50:12,489 --> 00:50:13,989 que nos ayude Eclipse 535 00:50:13,989 --> 00:50:17,289 vamos a meterlo con un try catch y listo 536 00:50:17,289 --> 00:50:18,989 ya está, pues fijaros 537 00:50:18,989 --> 00:50:20,949 esto, fizz que es 538 00:50:20,949 --> 00:50:21,949 un stream 539 00:50:21,949 --> 00:50:24,750 aquí podríamos coger y decir 540 00:50:24,750 --> 00:50:28,739 voy a buscar el copy pega 541 00:50:28,739 --> 00:50:37,539 podríamos decir, en lugar de trabajar con 542 00:50:37,539 --> 00:50:39,440 un stream, esto en verdad va a estar basado 543 00:50:39,440 --> 00:50:41,599 en caracteres, voy a utilizar un objeto 544 00:50:41,599 --> 00:50:43,599 de la clase scanner, pero en lugar 545 00:50:43,599 --> 00:50:45,599 de leer de system.in que era un stream 546 00:50:45,599 --> 00:50:47,360 ahora voy a leer de esto 547 00:50:47,360 --> 00:51:20,090 que es un string, aunque el otro lado de la, hay un lado de la tubería pinchado en mi programa, el otro lado está pinchado un fichero, no está pinchado al teclado, pues aquí se lo indicamos, veis, con el fichero del string, ahora que será, pues leerá, este dime algo ahora sobra, porque realmente no queremos que nos muestre esto por pantalla, esto lo ponemos como avisa nosotros mismos, porque tenemos que escribir algo por teclado, en este caso la lectura del 548 00:51:20,090 --> 00:51:25,530 fichero la va a hacer directamente y como es un objeto de la clase escáner 549 00:51:25,530 --> 00:51:30,150 que tiene disponible el nest line va a leer línea a línea con formato ya de 550 00:51:30,150 --> 00:51:33,269 carácter con lo cual no va a poder devolver un string que mostramos por 551 00:51:33,269 --> 00:51:37,969 pantalla y este objeto de escáner en realidad está pinchado un string y este 552 00:51:37,969 --> 00:51:41,969 string resulta que ha resultado ser un fichero 553 00:51:41,969 --> 00:51:49,079 entonces hacemos aquí una ejecución pero por aquí fijaros como me dice aquí un 554 00:51:49,079 --> 00:51:51,260 hola, y si yo cojo 555 00:51:51,260 --> 00:51:54,480 y vuelvo a editar el fichero 556 00:51:54,480 --> 00:51:58,480 y pongo una primera línea con hola y una segunda con adiós 557 00:51:58,480 --> 00:52:01,019 tiene ahora dos líneas, hola y adiós 558 00:52:01,019 --> 00:52:04,099 hago una ejecución y me dice hola 559 00:52:04,099 --> 00:52:05,800 ¿por qué? porque he leído un next line 560 00:52:05,800 --> 00:52:09,440 pero si yo ahora cojo aquí y hago 561 00:52:09,440 --> 00:52:16,250 un segundo next line 562 00:52:16,250 --> 00:52:21,210 pues me leerá dos líneas, una primera que dirá hola 563 00:52:21,210 --> 00:52:26,090 y una segunda que dirá adiós. En cada una de estas líneas hemos hecho una lectura, ¿verdad? 564 00:52:26,289 --> 00:52:31,769 Un next line, un segundo next line, método disponible en la clase scanner a través de este objeto 565 00:52:31,769 --> 00:52:39,150 que está enchufado al fichero. Hemos leído dos líneas, pues nos han mostrado una línea y una segunda línea. 566 00:52:39,150 --> 00:52:45,690 Por aquí lo tenéis. Mecanismo, pues el mismo que venimos haciendo todo el tiempo cuando hemos estado leyendo 567 00:52:45,690 --> 00:52:52,150 system in lo único que ahora hemos trabajado con otra clase que tenemos por 568 00:52:52,150 --> 00:52:56,369 aquí en lugar de con la clase del input string directamente con el que está 569 00:52:56,369 --> 00:53:01,710 asociado él con el que está asociado él 570 00:53:01,710 --> 00:53:12,789 la entrada información por teclado alguna preguntilla por ahí que si eso 571 00:53:12,789 --> 00:53:22,929 ocurra una cosa interesante que ya os insistía que no estoy haciendo yo ahora 572 00:53:22,929 --> 00:53:24,010 porque está acabando el programa 573 00:53:24,010 --> 00:53:27,190 me refiero a que está acabando el programa porque acaba el main 574 00:53:27,190 --> 00:53:28,889 que es interesante hacer 575 00:53:28,889 --> 00:53:30,730 y que os lo comentaba ya también 576 00:53:30,730 --> 00:53:32,409 para hacer siempre con escáner 577 00:53:32,409 --> 00:53:35,210 es que vayáis cerrando los flujos 578 00:53:35,210 --> 00:53:37,730 los flujos estos 579 00:53:37,730 --> 00:53:39,190 pues tienen la posibilidad 580 00:53:39,190 --> 00:53:41,190 del método que con escáner siempre 581 00:53:41,190 --> 00:53:43,210 os he dicho, acordaros de cerrar 582 00:53:43,210 --> 00:53:48,820 el flujo, aquí está definido 583 00:53:48,820 --> 00:53:50,920 este nivel, fijaros como tienen 584 00:53:50,920 --> 00:53:52,780 el método close, pues igual que el método 585 00:53:52,780 --> 00:53:54,820 escáner, pues lo tenía también 586 00:53:54,820 --> 00:53:55,380 pues para 587 00:53:55,380 --> 00:53:59,079 para que se quede cerrado, si se acaba el programa 588 00:53:59,079 --> 00:54:04,000 porque finaliza el main, en cualquier caso al acabar el programa 589 00:54:04,000 --> 00:54:08,099 se va a cerrar, pero si el programa, imaginaos que se mantiene activo 590 00:54:08,099 --> 00:54:11,800 continuamente, es un programa 24-7, si vais abriendo flujos y luego 591 00:54:11,800 --> 00:54:15,300 ir cerrando, pues al final vamos estropeando un poco la memoria RAM 592 00:54:15,300 --> 00:54:19,920 de hacer reserva de recursos 593 00:54:19,920 --> 00:54:24,019 que no cerramos y bueno, pues siempre nos puede terminar dando algún problema 594 00:54:24,019 --> 00:54:36,809 a ver más cosas por ahí que os puedo ir contando hemos estado todo el rato trabajando con input 595 00:54:36,809 --> 00:54:44,550 stream pues mira vamos a ver ahora salida está trabajando un poco por este lado con el input 596 00:54:44,550 --> 00:54:50,730 string con el file input string vamos un poquito ahora este lado el del output string y una de las 597 00:54:50,730 --> 00:54:56,789 cosas que podemos hacer por ejemplo es escribir en un fichero con el con el file output string 598 00:54:56,789 --> 00:55:01,230 si hacemos un file output string que escribiremos, escribiremos bytes 599 00:55:01,230 --> 00:55:02,849 venga, vamos a ello 600 00:55:02,849 --> 00:55:32,849 fijaros, estamos trabajando con string, vamos a escribir bytes 601 00:55:32,849 --> 00:55:36,769 en este caso para salida, no como antes con para entrada 602 00:55:36,769 --> 00:55:40,650 y hemos pensado trabajar con un fichero 603 00:55:40,650 --> 00:55:44,349 es decir, la salida está enfocada a hacerla en un fichero 604 00:55:44,349 --> 00:55:48,730 con lo cual el fichero sobre el que vamos a escribir, se lo podemos pasar 605 00:55:48,730 --> 00:56:01,190 aquí como atributo, como parámetro. Vamos a poner File Feature Escritura. Se me queja porque no lo 606 00:56:01,190 --> 00:56:08,809 tenemos importado, lo importamos de Java.io y ahora se me queja porque las gestiones con ficheros 607 00:56:08,809 --> 00:56:15,829 siempre suelen estar gestionadas ante posibles excepciones, entonces le ponemos que le meta el 608 00:56:15,829 --> 00:56:21,320 try-catch, file no fun excepción. Vale, pues 609 00:56:21,320 --> 00:56:24,880 ahí tenemos un file output string, podríamos escribir 610 00:56:24,880 --> 00:56:29,239 ya en este ficherito de salida directamente en base 611 00:56:29,239 --> 00:56:31,820 a bytes, entonces si ponemos fold 612 00:56:31,820 --> 00:56:38,909 write, por aquí lo tenemos, fijaros 613 00:56:38,909 --> 00:56:42,429 que podemos escribir un array de bytes o un entero 614 00:56:42,429 --> 00:56:49,000 bueno y alguna otra alternativa que hay más por ahí, vamos a poner aquí 615 00:56:49,000 --> 00:57:02,679 valor valga 10 vamos a ponerlo que lo meta que añade la cláusula a este 616 00:57:02,679 --> 00:57:07,420 track del lío excepción si hacemos una ejecución ahora este 617 00:57:07,420 --> 00:57:14,840 programa fijaros como aquí hemos puesto directamente el nombre del fichero si 618 00:57:14,840 --> 00:57:19,559 poner sin poner mayor mayor dato en la ruta sobre donde se va a escribir el 619 00:57:19,559 --> 00:57:23,179 fichero con lo cual en principio se escribirá en la propia que tiene 620 00:57:23,179 --> 00:57:28,619 definida por defecto el proyecto que es como hemos dicho aquí en verdad colgando 621 00:57:28,619 --> 00:57:33,679 directamente del directorio del proyecto y decimos que escriba por ahí 622 00:57:33,679 --> 00:57:40,500 normalmente los flujos como que intentan escribir primero en una zona de memoria 623 00:57:40,500 --> 00:57:44,960 es intermedia en lugar de volcarlo a disco y luego lo vuelca a disco cuando 624 00:57:44,960 --> 00:57:47,780 él le va apareciendo entonces si queremos hacer un volcado a disco 625 00:57:47,780 --> 00:57:51,579 directamente solemos poner un flush que es lo que 626 00:57:51,579 --> 00:57:55,440 haces todo lo que tengas pendiente de escribir, escríbelo a disco 627 00:57:55,440 --> 00:57:59,659 y aquí podríamos poner si queremos un close 628 00:57:59,659 --> 00:58:03,639 es decir, abrimos el fichero por aquí, al definirlo 629 00:58:03,639 --> 00:58:07,559 con el constructor, escribimos, nos aseguramos que queda volcada la 630 00:58:07,559 --> 00:58:14,340 información en disco y cerramos el flujo, hacemos aquí una ejecución 631 00:58:14,340 --> 00:58:17,840 en realidad no hemos sacado nada por pantalla, el programa se nos ha 632 00:58:17,840 --> 00:58:21,920 terminado, si nos ponemos aquí ahora, hacemos un ls, fijaros como nos ha 633 00:58:21,920 --> 00:58:33,860 creado el ficherito este y si intentamos ver su información, fich de escritura, pues no se ve nada. 634 00:58:37,869 --> 00:58:49,280 Vamos a probar con 100 y ahí se ve una D. ¿Qué sucedía? Que habíamos escrito un 10 que probablemente 635 00:58:49,280 --> 00:58:56,960 era un carácter no visible, generaba, si te vas a la tabla ASCII, el valor 10 que habíamos intentado 636 00:58:56,960 --> 00:59:02,599 escribir pues igual no es nada no es nada no es nada visible en el momento en el que lo edita 637 00:59:02,599 --> 00:59:11,679 amor o el editor nano cambio de tiempo ya nos pone hay una vez qué sucede si volvemos a ejecutar este 638 00:59:11,679 --> 00:59:28,280 programa es que volvemos a tener la de y si ponemos aquí un 101 ahora tenemos una es decir el valor de 639 00:59:28,280 --> 00:59:35,360 valor del siguiente carácter que sucede que cada una de las ejecuciones nos está borrando la 640 00:59:35,360 --> 00:59:39,099 información anterior e introduciendo la nueva. Antes había una D, ¿verdad? 641 00:59:39,980 --> 00:59:43,219 Lo hemos vuelto a ejecutar con 101 y nos ha aparecido una E, pero la D 642 00:59:43,219 --> 00:59:47,519 ha desaparecido. Si sobre un flujo de strings 643 00:59:47,519 --> 00:59:51,260 queremos que en lugar de eliminar los datos anteriores 644 00:59:51,260 --> 00:59:55,300 del fichero e incluir los nuevos, nos vaya añadiendo, 645 00:59:55,380 --> 00:59:59,159 vaya haciendo un attach sobre la información anterior a la nueva, le podemos poner aquí 646 00:59:59,159 --> 01:00:03,199 un segundo parámetro que sería un true, por defecto 647 01:00:03,199 --> 01:00:07,460 que esto es añade, añade verdadero, si pones aquí false 648 01:00:07,460 --> 01:00:11,199 elimina el fichero y si no pones nada 649 01:00:11,199 --> 01:00:15,199 el valor por defecto es como false, entonces si ponemos aquí 650 01:00:15,199 --> 01:00:19,440 un true, salvamos y hacemos una ejecución nueva 651 01:00:19,440 --> 01:00:24,599 no venimos al fichero ahora, fijaros como ya tiene dos es, una de la anterior 652 01:00:24,599 --> 01:00:27,840 y otra de la nueva, vamos a hacer una ejecución poniendo aquí un 0 653 01:00:27,840 --> 01:00:39,820 y ahí tenemos la de, fijaros 654 01:00:39,820 --> 01:00:47,199 que estamos escribiendo a través de enteros vamos a vamos a hacer una escritura a través de un array 655 01:00:47,199 --> 01:01:00,800 ponemos aquí force right fijaros aquí nos ofrece la opción de meter un array de bytes en lugar de 656 01:01:00,800 --> 01:01:06,679 escribir de esta forma pero seguimos escribiendo bytes para que esto tenga algo de información 657 01:01:06,679 --> 01:01:26,739 Tendríamos que poner aquí un bear que en la posición 0 tenga un 100, que tenga un 101, en la posición 1, darle información al array. 658 01:01:30,349 --> 01:01:34,570 Y si hacemos ahora una ejecución, ahora mismo el fichero tiene EED, ¿verdad? 659 01:01:34,570 --> 01:01:39,389 Y vamos a ver si nos funciona. 660 01:01:42,019 --> 01:01:45,780 Fijaros, el EED y la DEF, que son estos tres. 661 01:01:45,780 --> 01:01:49,800 ha escrito directamente esa información, pero estamos escribiendo byte a byte 662 01:01:49,800 --> 01:01:53,780 ¿verdad? ¿por qué? porque es un stream, igual que con 663 01:01:53,780 --> 01:01:58,019 el system.in antes que leíamos con un stream y éramos capaces de encapsular la información 664 01:01:58,019 --> 01:02:01,719 pues tenemos la posibilidad de encapsular también datos 665 01:02:01,719 --> 01:02:05,840 que vayamos a escribir en un ficherito 666 01:02:05,840 --> 01:02:12,349 entonces del file output stream lo que podríamos 667 01:02:12,349 --> 01:02:16,110 hacer aquí es mirar por aquí como podemos encapsularlo 668 01:02:16,110 --> 01:02:46,530 Entonces el file output string que tenemos por aquí podemos decir, mira vamos a intentar encasularlo en, a ver, a ver, pues mirad una posibilidad, podría ser en un output string writer, writer nos escribe carácter a carácter y un string que es lo que tenemos en el file output string, un string lo convertimos en un writer, entonces tenemos un output de salida string writer. 669 01:02:46,530 --> 01:02:53,119 y este writer, igual que hacíamos antes por seguir toda la jugada 670 01:02:53,119 --> 01:02:57,119 este output stream writer, ya que tenemos de este de salida 671 01:02:57,119 --> 01:03:00,980 un writer, podemos intentar hacerlo para escribir a través de un buffer 672 01:03:00,980 --> 01:03:04,880 entonces podemos convertirlo en un buffer al reader, que es la misma jugada que hemos hecho antes 673 01:03:04,880 --> 01:03:08,920 del input stream, que lo hemos convertido en un input stream reader 674 01:03:08,920 --> 01:03:12,360 para lectura, y luego hemos utilizado un buffer al reader 675 01:03:12,360 --> 01:03:16,880 pues ahora del output, del file output stream 676 01:03:16,880 --> 01:03:21,800 podemos traernos ahora un outputStringWriter y ahora un bufferWriter 677 01:03:21,800 --> 01:03:25,940 bueno, es jugar un poco con todas estas clases 678 01:03:25,940 --> 01:03:33,599 y así nos evitamos tener que estar escribiendo byte a byte 679 01:03:33,599 --> 01:03:36,639 si es lo que nos interesa, imaginaos que es una imagen 680 01:03:36,639 --> 01:03:39,900 que estamos leyendo la de un fichero y pasando la otra 681 01:03:39,900 --> 01:03:42,599 y queremos leerla byte a byte y escribirla byte a byte 682 01:03:42,599 --> 01:03:45,900 pues ya está, leemos con un fileInputString 683 01:03:46,420 --> 01:03:49,199 byte a byte y escribimos con un fileOutputString 684 01:03:49,199 --> 01:03:51,599 byte a byte y tan a gusto 685 01:03:51,599 --> 01:03:58,440 podríamos hacerlo así también, entonces este file output stream 686 01:03:58,440 --> 01:04:01,619 hemos dicho que vamos a convertirlo en 687 01:04:01,619 --> 01:04:06,539 a un writer, queremos que siga siendo de salida, con lo cual le decimos 688 01:04:06,539 --> 01:04:09,920 output stream 689 01:04:09,920 --> 01:04:28,219 writer, recibirá 690 01:04:28,219 --> 01:04:30,760 un stream, verdad 691 01:04:30,760 --> 01:04:36,619 este es un stream de salida, leído desde un fichero 692 01:04:36,619 --> 01:04:42,159 fos, y queremos convertir ese stream 693 01:04:42,159 --> 01:04:46,380 en un writer, los writers son de salida 694 01:04:46,380 --> 01:04:48,000 siempre, pero bueno, es como se llama 695 01:04:48,000 --> 01:04:53,420 entonces vamos a importarlo de yojaba, y ahora tenemos un writer 696 01:04:53,420 --> 01:04:57,760 pero como nos interesa que ese writer trabajarlo como un buffer 697 01:04:57,760 --> 01:05:01,860 para que tenga mejores eficiencias, ya ese writer directamente tendría 698 01:05:01,860 --> 01:05:05,940 métodos para escribir, pero podemos todavía convertirlo en algo 699 01:05:05,940 --> 01:05:07,920 que tenga buffer, que gestione un buffer 700 01:05:07,920 --> 01:05:10,199 de memoria rampa a la hora de hacer las escrituras. 701 01:05:11,039 --> 01:05:12,059 Entonces podemos coger aquí 702 01:05:12,059 --> 01:05:28,690 y decir, este writer 703 01:05:28,690 --> 01:05:30,210 que me lo convierta en algo que 704 01:05:30,210 --> 01:05:32,889 se gestiona a través de buffer. 705 01:05:33,590 --> 01:05:34,829 Y lo vamos a hacer 706 01:05:34,829 --> 01:05:36,570 con un objeto de esa clase que es el 707 01:05:36,570 --> 01:05:36,889 bw. 708 01:05:38,690 --> 01:05:40,630 Hacemos tal que aquí, y ahora podemos hacer 709 01:05:40,630 --> 01:05:42,690 aquí un bw.write 710 01:05:47,469 --> 01:05:50,110 y este, fijaros como ya nos permite 711 01:05:50,110 --> 01:05:52,510 escribir strings, cadenas de caracteres 712 01:05:52,510 --> 01:05:53,449 completas. 713 01:05:53,449 --> 01:06:18,659 hacemos ahí un flush, vamos a hacer una cosa 714 01:06:18,659 --> 01:06:23,440 vamos a borrar el fichero y empezamos a escribirlo de nuevo 715 01:06:23,440 --> 01:06:25,760 ya no existe el fichero de escritura 716 01:06:25,760 --> 01:06:31,199 ejecutamos por aquí y hacemos ahora un more aquí 717 01:06:31,199 --> 01:06:37,340 y fijaros como tiene ese hola como estás que hemos escrito por aquí con el write 718 01:06:37,340 --> 01:06:44,449 si volvemos a ejecutar tenemos un hola como estás 719 01:06:44,449 --> 01:06:47,590 y otro hola como estás, uno detrás de otro 720 01:06:47,590 --> 01:06:52,409 fijaros que tenemos que vaya añadiendo 721 01:06:52,409 --> 01:06:55,730 por aquí, a ver, si ponemos aquí un barra N 722 01:06:55,730 --> 01:06:59,369 no tengo seguridad si el buffer greater nos va a meter una nueva línea 723 01:06:59,369 --> 01:07:14,239 vamos a escribirlo dos veces con una nueva línea, mirad como ha metido una nueva 724 01:07:14,239 --> 01:07:17,940 línea y en realidad este segundo también la ha metido y ahora 725 01:07:17,940 --> 01:07:22,139 volvería a escribir aquí, con el barra N podemos meter una nueva línea igual que cuando hacemos 726 01:07:22,139 --> 01:07:27,719 con el println, fijaros como va añadiendo todo el rato la información 727 01:07:27,719 --> 01:07:31,500 ¿por qué? porque tenemos aquí el attach este, si cogemos y hacemos así, fijaros 728 01:07:31,500 --> 01:07:41,869 bueno, nos queda esto del último flush que hemos hecho 729 01:07:41,869 --> 01:07:47,570 si hacemos otra nueva ejecución, a la hora de crear el fichero 730 01:07:47,570 --> 01:07:51,829 entiendo que se habrá borrado lo anterior y tendremos nuevamente dos líneas solo, no se ha añadido 731 01:07:51,829 --> 01:07:55,449 si ahora ponemos de nuevo el true aquí, para decir, oye 732 01:07:55,449 --> 01:07:59,130 que vaya, mantenga la información anterior y añada la nueva 733 01:07:59,130 --> 01:08:03,449 pues ahora ya tendríamos, entiendo, cuatro líneas, vamos a verlo, ahí lo tenéis 734 01:08:03,449 --> 01:08:31,670 Vale, pues eso si lo metemos en un Buffer Writer, tenemos, fijaros, tenemos bastantes posibilidades, lo hemos hecho a través de un Buffer Writer, también tenemos aquí un File Writer, vamos a probar con el File Writer, al final todos terminan escribiendo en un fichero y un poquillo como la que os guste más utilizar. 735 01:08:31,670 --> 01:08:35,369 vamos a probar un par de alternativas más 736 01:08:35,369 --> 01:08:45,899 aquí lo que hemos hecho ha sido abrir como un stream 737 01:08:45,899 --> 01:08:46,939 lo hemos convertido en un writer 738 01:08:46,939 --> 01:08:48,899 y lo hemos metido en un buffer en el writer 739 01:08:48,899 --> 01:08:50,680 pues otra posibilidad es 740 01:08:50,680 --> 01:08:53,060 venirnos por aquí y decir mira voy a abrir el fichero 741 01:08:53,060 --> 01:08:54,539 directamente como un file writer 742 01:08:54,539 --> 01:08:56,560 no quiero stream 743 01:08:56,560 --> 01:08:58,119 directamente esta clase ya 744 01:08:58,119 --> 01:09:01,159 probablemente lo de abrirlo como un stream y hacer esa conversión 745 01:09:01,159 --> 01:09:02,659 lo hará el constructor 746 01:09:02,659 --> 01:09:04,720 de esta clase, probablemente 747 01:09:04,720 --> 01:09:06,739 no sé claro, no he mirado el código pero probablemente 748 01:09:06,739 --> 01:09:09,180 sea como lo haga, directamente abra como un stream 749 01:09:09,180 --> 01:09:13,619 y ya todo este proceso que hemos hecho nosotros por pasos, lo hago ya aquí 750 01:09:13,619 --> 01:09:22,149 pero si cogemos y hacemos un FileWriter, hacemos un new 751 01:09:22,149 --> 01:09:43,119 le decimos el fichero que queremos abrir, y este pues nada 752 01:09:43,119 --> 01:09:47,600 tiene la opción de FileWriter 753 01:09:47,600 --> 01:09:50,140 método write 754 01:09:50,140 --> 01:09:54,199 sí, por aquí write, fijaros, también write 755 01:09:54,199 --> 01:10:06,409 hola de nuevo, hacemos un fw.close 756 01:10:06,409 --> 01:10:18,289 borrarlo, el fichero de escritura este, y así que lo genere 757 01:10:18,289 --> 01:10:27,479 de nuevo, le damos aquí a ejecutar, a ver que es lo que ha pasado aquí 758 01:10:27,479 --> 01:10:37,800 se me ha quedado ahí colgado esa instrucción de los comentarios 759 01:10:37,800 --> 01:10:45,920 de antes, vale, y ahí tenemos el Lula 760 01:10:45,920 --> 01:10:49,560 de nuevo, pues también a través de esta otra clase que tenemos 761 01:10:49,560 --> 01:10:53,640 en toda esta estructura por aquí, pues también lo podemos hacer, y luego 762 01:10:53,640 --> 01:10:57,680 para terminar un poco de ver esto y pasar a contaros otras 763 01:10:57,680 --> 01:11:05,840 cositas, ya por concluir vamos a algo que nos resulta también familiar, porque aquí estamos 764 01:11:05,840 --> 01:11:14,220 utilizando el método write, el file writer, por aquí también hemos utilizado el write, que bueno, en 765 01:11:14,220 --> 01:11:19,199 principio no parece que sean complicados, pero por irnos a algo mucho más familiar, que hemos dicho 766 01:11:19,199 --> 01:11:26,760 que era el system out antes, pues el system out habíamos dicho que era un print writer, 767 01:11:26,760 --> 01:11:36,760 es un PrintStream 768 01:11:36,760 --> 01:11:39,520 yo pensaba que era un PrintWriter 769 01:11:39,520 --> 01:11:43,000 tenía dudas si era un PrintStream o un PrintWriter 770 01:11:43,000 --> 01:11:45,079 en cualquier caso el PrintWriter tiene 771 01:11:45,079 --> 01:11:49,840 las opciones de métodos 772 01:11:49,840 --> 01:11:51,380 que tenemos con el System.out 773 01:11:51,380 --> 01:11:54,220 si definimos un objeto de la clase Print 774 01:11:54,220 --> 01:11:57,399 también estará aquí, aquí lo tenemos 775 01:11:57,399 --> 01:12:22,890 el print writer, este puede resultarnos cómodo porque si ponemos aquí 776 01:12:22,890 --> 01:12:26,789 un pw ahora y hacemos un, intentamos 777 01:12:26,789 --> 01:12:30,750 escribir, fijaros los métodos que tiene, el print, el print 778 01:12:30,750 --> 01:12:34,170 ln, que estamos muy acostumbrados a trabajar con ellos 779 01:12:34,170 --> 01:12:38,869 con el system out, entonces si definimos, aunque sea para escribir un fichero 780 01:12:38,869 --> 01:12:42,409 con un print writer, pues aquí podemos poner 781 01:12:42,409 --> 01:12:46,930 lo típico que ponemos de lo que queremos que nos salga por aquí en consola 782 01:12:46,930 --> 01:12:50,829 con estos métodos en lugar de utilizar métodos nuevos 783 01:12:50,829 --> 01:12:53,670 que nos podría costar más o igual nos acordamos menos 784 01:12:53,670 --> 01:12:56,489 que los que trabajamos normalmente con él 785 01:12:56,489 --> 01:12:58,850 porque los conocemos ya de System.out 786 01:12:58,850 --> 01:13:18,989 vamos a hacer otra ejecución 787 01:13:18,989 --> 01:13:30,949 ejecutamos por aquí, suponemos que hemos escrito 788 01:13:30,949 --> 01:13:33,470 ejemplo con PrintWriter 789 01:13:33,470 --> 01:13:37,789 entonces ponemos FitchX, ahí tenemos ejemplo con PrintWriter 790 01:13:37,789 --> 01:13:39,569 hacemos una nueva ejecución 791 01:13:39,569 --> 01:13:45,229 se mantiene lo mismo, yo creo que habrá borrado, veis, se ha borrado el anterior 792 01:13:45,229 --> 01:13:49,810 y no recuerdo ahora mismo si este, admito también aquí un true, yo creo que sí 793 01:13:49,810 --> 01:13:56,229 ah pues no, pues no, con print writer no te deja 794 01:13:56,229 --> 01:14:00,229 añadir nueva información en un fichero, directamente 795 01:14:00,229 --> 01:14:04,510 cuando haces un close, creas un objeto nuevo, ya no te deja hacer el attach 796 01:14:04,510 --> 01:14:07,970 si utilizas el print writer directamente, si quieres hacer eso 797 01:14:07,970 --> 01:14:12,289 pues te puedes ir por esta vía, hacerlo con un file output string 798 01:14:12,289 --> 01:14:18,460 y luego ir encasulando la información. Otra cosilla que deciros 799 01:14:18,460 --> 01:14:22,100 es que existe una clase que si no vemos hoy en la siguiente tutoría 800 01:14:22,100 --> 01:14:25,800 la repasamos un poco, aunque sea rápido por dejar 801 01:14:25,800 --> 01:14:29,939 tiempo en la siguiente tutoría también por si tenéis alguna duda que preguntarme 802 01:14:29,939 --> 01:14:34,180 que es la clase File. La clase File permite 803 01:14:34,180 --> 01:14:38,199 hacer diferentes cosas, ya os digo, si nos da tiempo hoy bien la vemos 804 01:14:38,199 --> 01:14:42,199 y si no el próximo día. Y además permite 805 01:14:42,199 --> 01:14:44,439 también identificar el nombre del fichero 806 01:14:44,439 --> 01:14:48,380 en lugar de con una cadena de caracteres 807 01:14:48,380 --> 01:14:49,960 aquí, fijaros, esto es un string 808 01:14:49,960 --> 01:14:54,149 igual que lo hemos puesto aquí, entre comillas 809 01:14:54,149 --> 01:14:55,890 podríamos haber definido una variable string 810 01:14:55,890 --> 01:14:56,350 s 811 01:14:56,350 --> 01:14:59,470 numFitch 812 01:14:59,470 --> 01:15:02,430 aquí haber puesto el nombre del fichero 813 01:15:02,430 --> 01:15:05,609 y haberse lo puesto aquí, ¿verdad? 814 01:15:05,670 --> 01:15:07,970 que es un string, sería el mismo constructor, en ambos 815 01:15:07,970 --> 01:15:08,609 casos sería 816 01:15:08,609 --> 01:15:11,989 una cadena de caracteres, pero 817 01:15:11,989 --> 01:15:13,189 está sobrecargado 818 01:15:13,189 --> 01:15:17,430 el constructor de estos métodos para aceptar 819 01:15:17,430 --> 01:15:21,270 también un objeto de la clase File. Entonces podemos poner aquí 820 01:15:21,270 --> 01:15:33,260 New File, lo importamos 821 01:15:33,260 --> 01:15:36,579 y ahora aquí en el constructor, en lugar de poner 822 01:15:36,579 --> 01:15:40,140 esto, el nombre del fichero entre comillas como un string, lo podemos poner como un objeto 823 01:15:40,140 --> 01:15:44,460 del método File. Bueno, podemos decir, pues esto es lo mismo, 824 01:15:44,460 --> 01:15:48,399 ¿no? Pues en este caso, a la hora de ponerse al constructor, bueno, pues es 825 01:15:48,399 --> 01:15:52,500 lo mismo, pero esta clase nos permite hacer más cosas 826 01:15:52,500 --> 01:15:56,239 como por ejemplo borrar un fichero, listar la información 827 01:15:56,239 --> 01:15:59,460 de un directorio. Ya os digo, si nos da tiempo, lo hacemos hoy. 828 01:16:00,920 --> 01:16:04,539 Y estas clases que tenemos por aquí 829 01:16:04,539 --> 01:16:08,020 disponibles para acceder a ficheros, están 830 01:16:08,020 --> 01:16:12,560 sobrecargadas para que en el constructor identifiquemos el fichero 831 01:16:12,560 --> 01:16:16,560 sobre el cual queremos trabajar con un string o bien con un objeto 832 01:16:16,560 --> 01:16:23,859 de la clase file. Otra clase que es más o menos 833 01:16:23,859 --> 01:16:26,819 que tiene que responder 834 01:16:26,819 --> 01:16:30,979 al término de serialización 835 01:16:30,979 --> 01:16:33,939 tiene que ver con guardar 836 01:16:33,939 --> 01:16:36,699 información de objetos que tenemos en nuestro 837 01:16:36,699 --> 01:16:39,800 programa para poder recuperarlos. Fijaros 838 01:16:39,800 --> 01:16:42,779 cuando nosotros hacemos un new de un objeto 839 01:16:42,779 --> 01:16:45,699 de cualquier clase, ¿qué es lo que 840 01:16:45,699 --> 01:16:48,779 sucede? Que ese objeto existe donde en memoria 841 01:16:48,779 --> 01:16:51,779 RAM. Si nosotros apagamos el programa, perderemos su 842 01:16:51,779 --> 01:16:54,859 información. ¿Qué tenemos que hacer? Pues hacer 843 01:16:54,859 --> 01:16:57,960 esa información persistente. Podríamos guardarla en ficheros, 844 01:16:58,640 --> 01:17:00,979 que es lo que vamos a hacer ahora, guardar cierta información 845 01:17:00,979 --> 01:17:03,920 de objetos en ficheros, meterlos en una base 846 01:17:03,920 --> 01:17:06,859 de datos para que fueran persistentes en una base de datos. La cosa 847 01:17:06,859 --> 01:17:09,899 es que lo tendríamos que guardar en algún sitio. Si nosotros 848 01:17:09,899 --> 01:17:12,640 ejecutamos un programa donde, no sé, 849 01:17:12,739 --> 01:17:16,239 una tienda donde van los clientes 850 01:17:16,239 --> 01:17:20,060 y ahora mismo hay tres clientes, o sea, en el momento de arrancar hay cero clientes, 851 01:17:20,140 --> 01:17:22,720 damos de alta a tres clientes que están comprando en ese momento, 852 01:17:23,579 --> 01:17:27,159 paramos el programa y lo volvemos a activar, pues la nueva activación, 853 01:17:27,279 --> 01:17:31,100 esos tres clientes no existirán. ¿Por qué? Porque los teníamos en objetos en memoria RAM 854 01:17:31,100 --> 01:17:36,039 y como la memoria RAM se libera cuando se cierra el programa, 855 01:17:36,220 --> 01:17:39,939 la nueva ejecución no hemos hecho ningún new para ningún nuevo cliente. 856 01:17:40,699 --> 01:17:44,939 Si queremos restablecer al mismo estado exactamente en el que se cierra la aplicación, 857 01:17:44,939 --> 01:17:48,199 pues tendríamos que ser capaces de guardar esos clientes que estaban 858 01:17:48,199 --> 01:17:53,640 y al arrancar la aplicación leer del sitio donde los hayamos guardado 859 01:17:53,640 --> 01:17:55,960 para tenerlos de nuevo disponibles. 860 01:17:57,140 --> 01:18:01,199 Una alternativa podría ser ir a atributo a atributo de esos objetos 861 01:18:01,199 --> 01:18:05,079 y guardar la información de cada uno de los atributos, leerlos luego y cargarlos 862 01:18:05,079 --> 01:18:09,579 hacer news de los objetos y cargarlos. Y otra, digamos más eficiente 863 01:18:09,579 --> 01:18:13,180 es guardar el objeto en sí a través del proceso de serialización 864 01:18:13,180 --> 01:18:18,319 que creo que os aparece en los apuntes 865 01:18:18,319 --> 01:18:20,039 y bueno, vamos a hacer un pequeño ejemplo 866 01:18:20,039 --> 01:18:22,699 porque es muy sencillo y se hace muy rápido 867 01:18:22,699 --> 01:18:32,579 vamos a suponer que en este proyecto 868 01:18:32,579 --> 01:18:36,180 tenemos la clase tan socorrida en tantos ejemplos 869 01:18:36,180 --> 01:18:37,159 la clase persona 870 01:18:37,159 --> 01:18:44,420 la clase persona tendría todos sus atributos 871 01:18:44,420 --> 01:18:45,579 y todos sus métodos 872 01:18:45,579 --> 01:18:47,560 vamos a entender que tiene 873 01:18:47,560 --> 01:18:53,460 es un atributo donde tenga el nombre, también 874 01:18:53,460 --> 01:18:57,840 socorrido siempre, ¿verdad? Y un entero donde tenga 875 01:18:57,840 --> 01:19:04,739 la edad. Lógicamente tendría todos los métodos que correspondiesen. 876 01:19:05,619 --> 01:19:08,659 La clase persona, aquí para la serialización no nos vamos a preocupar 877 01:19:08,659 --> 01:19:12,060 mucho de ello. Vamos a dejarlo de momento así y no dedicamos más tiempo 878 01:19:12,060 --> 01:19:16,159 a esto. Entonces aquí en el programa, pues como siempre 879 01:19:16,159 --> 01:19:18,920 podríamos crear personas. Entonces decimos persona 880 01:19:18,920 --> 01:19:21,100 p1 881 01:19:21,100 --> 01:19:23,680 igual a 882 01:19:23,680 --> 01:19:25,579 new persona 883 01:19:25,579 --> 01:19:27,680 aquí 884 01:19:27,680 --> 01:19:29,399 podríamos tener un constructor copia 885 01:19:29,399 --> 01:19:31,819 una inicialización, todo lo que fuese 886 01:19:31,819 --> 01:19:33,739 ya os digo que no nos vamos a preocupar 887 01:19:33,739 --> 01:19:35,340 mucho, vamos a darle unos datos aquí 888 01:19:35,340 --> 01:19:36,800 de momento, ese nombre 889 01:19:36,800 --> 01:19:43,899 p1.i edad 890 01:19:43,899 --> 01:19:46,739 vamos a decir que no tiene 25 años 891 01:19:46,739 --> 01:19:49,899 vamos a crear una segunda persona 892 01:19:49,899 --> 01:20:05,750 y que vale, ya tiene 35 893 01:20:05,750 --> 01:20:08,270 vale, pues ya tenemos aquí 894 01:20:08,270 --> 01:20:10,449 dos personas 895 01:20:10,449 --> 01:20:12,189 que por aquí seguirían 896 01:20:12,189 --> 01:20:13,930 haciendo su lógica de programa normal 897 01:20:13,930 --> 01:20:16,449 y resulta que si apagamos 898 01:20:16,449 --> 01:20:18,250 el programa, pues esas dos personas 899 01:20:18,250 --> 01:20:20,529 ahora mismo perderíamos toda su información 900 01:20:20,529 --> 01:20:22,390 ¿por qué? pues porque está en memoria RAM 901 01:20:22,390 --> 01:20:24,229 que se ha reservado, como hemos 902 01:20:24,229 --> 01:20:26,109 dicho tantas veces, en el momento en el que hemos hecho 903 01:20:26,109 --> 01:20:27,470 el new y se ha inicializado 904 01:20:27,470 --> 01:20:28,869 a través del 905 01:20:28,869 --> 01:20:31,350 constructor persona 906 01:20:31,350 --> 01:20:33,989 por defecto en este caso, porque no lo hemos 907 01:20:33,989 --> 01:20:42,199 programado. Tengo comentado más cosas de las que debiera 908 01:20:42,199 --> 01:20:49,380 por ahí y no me compila. Vale, ya compila. 909 01:20:50,640 --> 01:20:54,699 Vale, pues para guardar información 910 01:20:54,699 --> 01:20:58,640 que queramos tener en un momento dado de diferentes 911 01:20:58,640 --> 01:21:01,800 clases que tengamos en el programa, podemos utilizar 912 01:21:01,800 --> 01:21:07,159 las clases Object Output Stream. 913 01:21:09,670 --> 01:21:10,970 A ver dónde estaba por ahí. 914 01:21:10,970 --> 01:21:15,770 OutputStream, ObjectOutputStream 915 01:21:15,770 --> 01:21:19,909 para guardar información, para enviar 916 01:21:19,909 --> 01:21:23,090 a través de un flujo objetos y 917 01:21:23,090 --> 01:21:27,789 el ObjectInputStream para leerlos. Imaginaos que estamos 918 01:21:27,789 --> 01:21:32,170 comunicando dos aplicaciones. Pues en una podríamos implementar 919 01:21:32,170 --> 01:21:35,670 el ObjectInputStream para coger streams que serán objetos 920 01:21:35,670 --> 01:21:41,270 y desde la otra hacer el ObjectOutputStream. Esto es para 921 01:21:41,270 --> 01:21:46,390 comunicar dos aplicaciones que están en marcha y queremos pasarle ciertos objetos de la clase 922 01:21:46,390 --> 01:21:51,909 persona de una a otra para que la segunda tenga la información de los objetos que se han dado de 923 01:21:51,909 --> 01:21:58,510 alta en la primera. Otra posibilidad sería, oye mira, los objetos que tenemos a través de un 924 01:21:58,510 --> 01:22:04,409 object output stream vamos a guardarlos en un ficherito. Entonces podríamos definir un fichero 925 01:22:04,409 --> 01:22:08,970 file output stream, vamos a escribir un stream en un fichero de salida 926 01:22:08,970 --> 01:22:13,390 y a este decirle que la información 927 01:22:13,390 --> 01:22:17,489 le va a venir desde un object output stream 928 01:22:17,489 --> 01:22:20,890 es decir, el object output stream se va a guardar en un fichero, con lo cual 929 01:22:20,890 --> 01:22:24,949 estos en lugar de enviárselos a otra aplicación, en este caso lo estaríamos dejando registrados 930 01:22:24,949 --> 01:22:29,470 en un ficherito y luego en una siguiente ejecución de la aplicación 931 01:22:29,470 --> 01:22:32,170 o desde otra aplicación, lo que haríamos sería 932 01:22:32,170 --> 01:22:37,449 desde un fichero, un FileInputString, leer la información 933 01:22:37,449 --> 01:22:41,789 como si fueran objetos a través de la clase ObjectInputString 934 01:22:41,789 --> 01:22:45,069 y ahí ya los damos de alta de nuevo como objetos 935 01:22:45,069 --> 01:22:49,430 del programa, en este caso objetos de tipo persona 936 01:22:49,430 --> 01:22:53,050 entonces si cogemos y primero hacemos 937 01:22:53,050 --> 01:22:57,270 el almacenamiento, lo que diremos, mira vamos a guardar información en un 938 01:22:57,270 --> 01:23:03,939 fichero, decimos FileOutputString 939 01:23:03,939 --> 01:23:09,899 fijaros que ahora no vamos a encapsular esto como como readers ni como writers porque pues porque 940 01:23:10,420 --> 01:23:17,100 queremos guardar los objetos como bytes directamente no queremos que tengan un formato para procesarlo como caracteres 941 01:23:19,920 --> 01:23:21,920 podemos poner el file output stream 942 01:23:22,979 --> 01:23:33,000 igual a new y aquí el fichero vamos a llamarlo 943 01:23:34,319 --> 01:23:36,819 vamos a llamarlo que deciros 944 01:23:36,819 --> 01:23:55,199 personas persona punto obj obj lo voy a llamar por objeto al nombre del fichero esto es algo 945 01:23:55,199 --> 01:24:02,039 esto no va a permitir escribir un stream en forma de salida en un fichero pero el origen de esa 946 01:24:02,039 --> 01:24:06,260 información de dónde va a venir pues va a venir de un objeto de lo que vamos a hacer va a ser 947 01:24:06,260 --> 01:24:16,260 escribir sobre objetos, object, object output stream, output stream por aquí, el object output stream 948 01:24:16,260 --> 01:24:46,010 y este object output screen queremos que en particular se dirija a un ficherito que hemos 949 01:24:46,010 --> 01:24:55,949 dado de alta aquí. Eso lo indicamos ahí en el constructor. Importamos y decimos que añada el 950 01:24:55,949 --> 01:25:07,460 excepción aquí como clave y ahora lo que vamos a hacer aquí es que sobre el oye output stream lo 951 01:25:07,460 --> 01:25:13,800 que haga es que escriba nos da diferentes opciones por aquí pero lo que nos interesa es que escriba 952 01:25:13,800 --> 01:25:20,539 un objeto veis y qué objeto vamos a querer que escriba pues mira vamos a decirle que escriba 953 01:25:20,539 --> 01:25:29,060 el objeto P1 y le vamos a decir que escriba el objeto 954 01:25:29,060 --> 01:25:36,210 P2. Hacemos un flush 955 01:25:36,210 --> 01:25:44,010 y lo vamos a cerrar. Aquí lo que estamos haciendo es 956 01:25:44,010 --> 01:25:48,710 utilizando esta clase que se ha especializado en escribir información de objetos 957 01:25:48,710 --> 01:25:52,210 lo encasulamos dentro 958 01:25:52,210 --> 01:25:56,470 de una clase que escribe streams en un fichero y ahora 959 01:25:56,470 --> 01:25:59,050 hacemos las escrituras a través del writeObject 960 01:25:59,050 --> 01:26:03,899 en un ficherito que se va terminando 961 01:26:03,899 --> 01:26:05,800 llamando persona.obj 962 01:26:05,800 --> 01:26:08,640 y me dice aquí 963 01:26:08,640 --> 01:26:11,300 la clase persona no es serializable 964 01:26:11,300 --> 01:26:13,359 entonces no tejo 965 01:26:13,359 --> 01:26:15,000 os acordáis de la palabra 966 01:26:15,000 --> 01:26:16,359 serializable que decíamos 967 01:26:16,359 --> 01:26:19,079 esto es porque aquellas clases 968 01:26:19,079 --> 01:26:21,060 que vayamos a utilizar para escribir como 969 01:26:21,060 --> 01:26:22,859 objetos, tenemos que 970 01:26:22,859 --> 01:26:25,260 indicarles que implementen 971 01:26:25,260 --> 01:26:26,279 un interfaz 972 01:26:26,279 --> 01:26:27,140 es el 973 01:26:27,140 --> 01:26:28,800 implements 974 01:26:28,800 --> 01:26:38,829 serializable, lo importamos 975 01:26:38,829 --> 01:26:42,970 y ya está, fijaros que hay que implementar el interfaz, las librerías 976 01:26:42,970 --> 01:26:46,310 de Java por estos métodos lo precisarán 977 01:26:46,310 --> 01:26:50,829 pero en realidad no tenemos que sobrescribir ningún método, que normalmente lo que 978 01:26:50,829 --> 01:26:55,050 nos obligan los interfaces es luego a sobrescribir métodos, pues no hay que sobrescribir 979 01:26:55,050 --> 01:26:58,729 nada, simplemente hace referencia a que implemente serializable 980 01:26:58,729 --> 01:27:04,659 para que no se nos queje aquí, lo vamos a ejecutar por aquí 981 01:27:04,659 --> 01:27:08,399 parece que no se ha quejado con errores 982 01:27:08,399 --> 01:27:11,399 vamos a ver si existe el fichero persona.bj 983 01:27:11,399 --> 01:27:18,729 ahí está, y fijaros, tiene ahí datos 984 01:27:18,729 --> 01:27:21,670 bueno, pues que él se las ha arreglado para guardarlo 985 01:27:21,670 --> 01:27:25,010 como haya sido, no son datos legibles 986 01:27:25,010 --> 01:27:27,909 desde nuestra perspectiva humana 987 01:27:27,909 --> 01:27:30,649 sí que es verdad que hay cosillas por ahí que parece que 988 01:27:30,649 --> 01:27:33,369 se quieren leer, iría por ahí, pero no es 989 01:27:33,369 --> 01:27:38,720 entendible al 100%, bien pues ya tenemos 990 01:27:38,720 --> 01:27:42,520 guardado eso. ¿Qué sucede? Que ahora podría interesarnos 991 01:27:42,520 --> 01:27:45,619 en otra ejecución del programa, arrancarlo bajo 992 01:27:45,619 --> 01:27:47,859 esta situación. 993 01:27:50,829 --> 01:27:58,710 Se me ha colgado esta máquina, la máquina virtual. 994 01:28:03,180 --> 01:28:06,140 No voy a andar dándole mucha vuelta, la voy a parar y la voy a arrancar de nuevo. 995 01:28:19,609 --> 01:28:24,130 Lo que vamos a hacer ahora va a ser, os cuento mientras arranca, 996 01:28:25,970 --> 01:28:30,069 irnos al input, a través 997 01:28:30,069 --> 01:28:33,989 de un file inputString, hacer un object inputString para cargar 998 01:28:33,989 --> 01:28:47,760 esos datos que hemos guardado antes, a ver, espero que no se nos hayan perdido 999 01:28:47,760 --> 01:29:14,779 los datos que teníamos guardados del proyecto, a ver, a ver 1000 01:29:14,779 --> 01:29:33,420 por aquí estábamos, entonces ahora cogemos 1001 01:29:33,420 --> 01:29:37,699 voy a comentar esto, se supone que viene otro 1002 01:29:37,699 --> 01:29:41,819 programa, viene este, en otra ejecución, lo que queremos hacer es 1003 01:29:41,819 --> 01:29:45,399 oye mira, vamos a arrancar partiendo del estado en el que 1004 01:29:45,399 --> 01:30:00,439 pudo parar aquel programa que era con estos dos objetos cargados, entonces para eso lo que hacemos ahora es definir un FileInputStream, 1005 01:30:04,569 --> 01:30:29,560 este FileInputStream queremos leer la información que tiene este fichero que habíamos guardado antes en disco, vamos a volver aquí al directorio, 1006 01:30:29,560 --> 01:30:39,520 recordad que teníamos el fichero este con esa información 1007 01:30:39,520 --> 01:30:43,579 que bueno, no se entendía muy bien, y le había guardado el 1008 01:30:43,579 --> 01:30:48,159 file output stream, queremos volver 1009 01:30:48,159 --> 01:30:56,289 a leer el mismo ficherito, nos va a obligar a hacer un try catch 1010 01:30:56,289 --> 01:31:02,239 por aquí, y lo queremos leer en formato 1011 01:31:02,239 --> 01:31:06,100 de objetos, fijaros que es un poco el reflejo de esto 1012 01:31:06,100 --> 01:31:09,300 aquí teníamos el file output stream, file input stream 1013 01:31:09,300 --> 01:31:11,100 y ahora el object 1014 01:31:11,100 --> 01:31:12,779 output stream, pues que pondremos aquí 1015 01:31:12,779 --> 01:31:13,880 un object 1016 01:31:13,880 --> 01:31:16,779 input stream 1017 01:31:16,779 --> 01:31:29,579 new 1018 01:31:29,579 --> 01:31:31,680 y a este 1019 01:31:31,680 --> 01:31:33,260 object input stream le metemos 1020 01:31:33,260 --> 01:31:34,680 el file input stream 1021 01:31:34,680 --> 01:31:46,239 importamos, añadimos 1022 01:31:46,239 --> 01:31:48,060 la cláusula 1023 01:31:48,060 --> 01:31:49,300 por aquí del iobsection 1024 01:31:49,300 --> 01:31:51,800 y ya estamos en disposición de leer 1025 01:31:51,800 --> 01:31:52,579 objetos 1026 01:31:52,579 --> 01:31:58,159 el object input stream 1027 01:31:58,159 --> 01:31:58,779 lo hacemos 1028 01:31:58,779 --> 01:32:01,260 si aquí hacíamos 1029 01:32:01,260 --> 01:32:03,680 un write 1030 01:32:03,680 --> 01:32:04,300 pues aquí 1031 01:32:04,300 --> 01:32:07,199 entiendo que será un read object 1032 01:32:07,199 --> 01:32:08,399 read object 1033 01:32:08,399 --> 01:32:10,699 y lo que nos devuelve es un objeto 1034 01:32:10,699 --> 01:32:12,420 del tipo que 1035 01:32:12,420 --> 01:32:18,800 toque, fijaros que devuelve 1036 01:32:18,800 --> 01:32:20,659 algo como 1037 01:32:20,659 --> 01:32:22,699 object, es decir es genérico total 1038 01:32:22,699 --> 01:32:24,479 entonces como lo que vamos a leer 1039 01:32:24,479 --> 01:32:26,319 va a ser una persona, vamos a hacerle aquí un casting 1040 01:32:26,319 --> 01:32:28,779 para que 1041 01:32:28,779 --> 01:32:31,119 convierta la referencia 1042 01:32:31,119 --> 01:32:38,859 object a una referencia a la clase persona y ahora lo que podemos hacer aquí es definir persona 1043 01:32:38,859 --> 01:32:49,260 per una leída, fijaros no lo hago un new, directamente simplemente es un dedito para apuntar donde toque 1044 01:32:49,260 --> 01:32:58,909 y decimos que apunte a la posición de memoria que nos diga esto, read object nos dice que 1045 01:32:58,909 --> 01:33:04,229 añadíamos la cláusula, dice class no phone exception, 1046 01:33:04,470 --> 01:33:08,029 también la necesita, entonces esta persona 1047 01:33:08,029 --> 01:33:11,869 estará apuntando a un objeto 1048 01:33:11,869 --> 01:33:16,090 que acabaremos de leer de aquí, que por la secuencia 1049 01:33:16,090 --> 01:33:20,010 de la escritura anterior, pues será la misma información que tenía P1, 1050 01:33:20,430 --> 01:33:24,170 P1 recordad que antes cuando lo hemos escrito era NOA con edad de 25, 1051 01:33:24,890 --> 01:33:27,890 entonces se entiende que ahora PER1 leída estará 1052 01:33:27,890 --> 01:33:34,029 apuntando a los datos que antes habíamos guardado en el fichero para NOA P1. 1053 01:33:35,449 --> 01:34:03,880 Vamos aquí a hacer un System of Println y ponemos aquí edad también. 1054 01:34:09,199 --> 01:34:13,619 Hemos cargado aquí la información desde el fichero a través de esta lectura 1055 01:34:13,619 --> 01:34:17,800 que sabemos porque es un fichero que hemos creado nosotros antes 1056 01:34:17,800 --> 01:34:23,960 que corresponde a esta escritura de un objeto de una clase persona P1 1057 01:34:23,960 --> 01:34:26,300 a la que le habíamos dado estos datos 1058 01:34:26,300 --> 01:34:33,140 y ya que habíamos guardado dos, pues vamos a hacer una lectura 1059 01:34:33,140 --> 01:34:34,819 del fichero de la segunda de las personas 1060 01:34:34,819 --> 01:34:37,100 y repetimos 1061 01:34:37,100 --> 01:34:44,560 toda la jugada, volvemos a hacer una lectura 1062 01:34:44,560 --> 01:34:46,119 ahora la lectura del siguiente, porque 1063 01:34:46,119 --> 01:34:47,779 en este avanzó el cursor 1064 01:34:47,779 --> 01:34:50,279 en el fichero y se quedó pendiente de la lectura 1065 01:34:50,279 --> 01:34:51,460 de la segunda de las personas 1066 01:34:51,460 --> 01:35:00,430 entonces ejecutamos por aquí 1067 01:35:00,430 --> 01:35:06,869 y fijaros como efectivamente nos ha mostrado los datos 1068 01:35:06,869 --> 01:35:07,989 de la lectura 1069 01:35:07,989 --> 01:35:09,289 con una edad de 0 1070 01:35:09,289 --> 01:35:13,189 edad 0 1071 01:35:13,189 --> 01:35:46,949 1, 1, 2, 2, no ha funcionado bien del todo esto, fijaros como nos está diciendo que no, tiene edad 35, que tenía 25, y Valeria no dice edad 0, que tenía 35 1072 01:35:46,949 --> 01:36:09,270 vamos a borrarlo, vamos a hacer otra ejecución creando el fichero de nuevo, porque como estamos tocando el código no vaya a ser que hayamos liado alguna 1073 01:36:09,270 --> 01:36:29,350 voy a volver a guardar los datos p1 p2 ejecuto ya está persona bj y ahora les comento esta otra 1074 01:36:29,350 --> 01:36:40,260 parte que es en la que estamos leyendo pues nada me da estos datos no sé qué estoy haciendo mal 1075 01:36:40,260 --> 01:37:00,989 algo algo estoy haciendo mal no sé si entiendo que veis lo que está pasando porque cuando guardo 1076 01:37:00,989 --> 01:37:03,369 los datos, guardo, ah vale 1077 01:37:03,369 --> 01:37:03,890 mirad 1078 01:37:03,890 --> 01:37:07,529 vale, aquí está la explicación, es que al guardarlo 1079 01:37:07,529 --> 01:37:09,289 estoy guardando aquí P1 edad 1080 01:37:09,289 --> 01:37:11,569 no estoy modificando P2 edad 1081 01:37:11,569 --> 01:37:12,869 sino P1 edad 1082 01:37:12,869 --> 01:37:15,090 entonces P2 edad vale 0 1083 01:37:15,090 --> 01:37:17,069 efectivamente, y P1 edad 1084 01:37:17,069 --> 01:37:18,869 lo estoy sobrescribiendo a 35 1085 01:37:18,869 --> 01:37:21,409 vale, que bueno 1086 01:37:21,409 --> 01:37:23,289 es que las cosas tengan explicación 1087 01:37:23,289 --> 01:37:24,829 aquí tengo un error 1088 01:37:24,829 --> 01:37:27,529 he mantenido P1 del copy-paste anterior y esto tiene que ser 1089 01:37:27,529 --> 01:37:33,569 P2, lo voy a borrar de nuevo 1090 01:37:33,569 --> 01:37:34,670 vamos a hacer una ejecución 1091 01:37:34,670 --> 01:37:39,409 porque no tiene esto mucho más misterio 1092 01:37:39,409 --> 01:37:48,409 como para que no funcione, descomento de nuevo para guardar 1093 01:37:48,409 --> 01:37:50,390 el fichero, el fichero ahora 1094 01:37:50,390 --> 01:37:55,869 persona obj no está existiendo, le doy una ejecución 1095 01:37:55,869 --> 01:38:02,840 ya tenemos ahí persona obj, después de haber hecho el cambio de ese error que teníamos 1096 01:38:02,840 --> 01:38:13,739 en el programa, me vengo por aquí, descomento para la lectura 1097 01:38:13,739 --> 01:38:21,140 y bueno, ahora ya sí que coge los datos desde el fichero 1098 01:38:21,140 --> 01:38:23,319 como era de esperar, para la persona 1 1099 01:38:23,319 --> 01:38:24,800 dice que es nueva con edad 25 1100 01:38:24,800 --> 01:38:27,479 y la persona 2 que es Valeria con edad 35 1101 01:38:27,479 --> 01:38:31,140 bueno, pues esa sería una posibilidad 1102 01:38:31,140 --> 01:38:33,060 de, dentro de todas 1103 01:38:33,060 --> 01:38:34,939 estas, en este caso de guardar 1104 01:38:34,939 --> 01:38:36,859 objetos, y fijaros 1105 01:38:36,859 --> 01:38:38,880 que bueno, pues hemos visto unas 1106 01:38:38,880 --> 01:38:40,640 cuantas, yo en verdad muchas 1107 01:38:40,640 --> 01:38:42,760 no sé exactamente para qué sirve, no las he 1108 01:38:42,760 --> 01:38:44,800 utilizado, pero hay muchas más 1109 01:38:44,800 --> 01:38:46,420 alternativas dentro de las librerías 1110 01:38:46,420 --> 01:38:48,819 las librerías son inmensas 1111 01:38:48,819 --> 01:38:50,920 las que tiene disponible Java, no solamente 1112 01:38:50,920 --> 01:38:52,800 en este ámbito, y estas 1113 01:38:52,800 --> 01:38:56,760 que os cuento, pues bueno, son un poco las que aparecen en la teoría y quizás las que 1114 01:38:56,760 --> 01:39:00,500 son más utilizadas, pero bueno, pues hay más por ahí que 1115 01:39:00,500 --> 01:39:04,720 estarán pensadas para algunas situaciones más en particular. 1116 01:39:07,659 --> 01:39:10,840 Aquí hemos, bueno, aquí hay 1117 01:39:10,840 --> 01:39:14,340 otra clase de la que habla también un poco la teoría, que es para accesos 1118 01:39:14,340 --> 01:39:18,960 random a posiciones aleatorias, no tanto 1119 01:39:18,960 --> 01:39:22,699 lo que hemos hecho ahora ha sido cuando escribimos 1120 01:39:22,699 --> 01:39:26,319 o leemos de un fichero, estamos haciendo un acceso 1121 01:39:26,319 --> 01:39:29,779 secuencial, es decir, si estamos escribiendo, si tenemos 1122 01:39:29,779 --> 01:39:34,500 un attach, pues escribe justo al final y la siguiente escritura 1123 01:39:34,500 --> 01:39:38,319 después y la siguiente después, siempre debajo. Cuando lo leemos 1124 01:39:38,319 --> 01:39:42,420 de igual forma, digamos que al abrir el fichero, el puntero 1125 01:39:42,420 --> 01:39:46,420 se pone en el primero de los registros, leemos ese registro y una vez leído ese registro 1126 01:39:46,420 --> 01:39:50,640 avanza al segundo registro, leerá el segundo registro, avanzará al tercero 1127 01:39:50,640 --> 01:39:52,560 así hasta que llegue el final de fichero 1128 01:39:52,560 --> 01:39:54,600 que normalmente se lee 1129 01:39:54,600 --> 01:39:56,399 la finalización de los flujos 1130 01:39:56,399 --> 01:39:58,000 como bien comentabais antes alguno 1131 01:39:58,000 --> 01:40:00,680 te devuelve un menos uno la lectura 1132 01:40:00,680 --> 01:40:01,460 típicamente 1133 01:40:01,460 --> 01:40:04,500 y existe la posibilidad de acceder a 1134 01:40:04,500 --> 01:40:06,159 ficheros de forma aleatorio, léeme 1135 01:40:06,159 --> 01:40:08,079 directamente un registro que esté en la posición 1136 01:40:08,079 --> 01:40:10,000 la que sea, si tienes la posibilidad 1137 01:40:10,000 --> 01:40:12,039 del programa de conocerlo, pues eso 1138 01:40:12,039 --> 01:40:14,140 se podrá gestionar desde 1139 01:40:14,140 --> 01:40:16,420 la estructura 1140 01:40:16,420 --> 01:40:18,439 esta de árbol de random access file 1141 01:40:18,439 --> 01:40:23,140 bueno, para meter tokens 1142 01:40:23,140 --> 01:40:25,979 por aquí que diferencien unos tipos de datos 1143 01:40:25,979 --> 01:40:28,880 de otro, para, imaginaos que en un fichero queréis meter 1144 01:40:28,880 --> 01:40:32,439 enteros, doubles, strings 1145 01:40:32,439 --> 01:40:34,920 todo mezclado, hay uno detrás de otro, pues se puede 1146 01:40:34,920 --> 01:40:37,859 tokenizar, es decir, poner identificadores 1147 01:40:37,859 --> 01:40:41,220 de cada uno de los datos, creo recordar que era esta clase 1148 01:40:41,220 --> 01:40:44,000 y la otra que 1149 01:40:44,000 --> 01:40:47,199 se trata en el tema y que también tiene cierto interés 1150 01:40:47,199 --> 01:40:49,420 es la file esta que os la he referido 1151 01:40:49,420 --> 01:40:53,119 porque a la hora de definir el fichero al que se quiera acceder 1152 01:40:53,140 --> 01:40:59,880 En el constructor se puede poner como un string o como un objeto de la clase File, pero es capaz de hacer bastante más cosas. 1153 01:41:01,340 --> 01:41:04,699 Y no sé si que empecemos a hacer algo 10 minutillos, yo creo que sí. 1154 01:41:08,689 --> 01:41:11,069 Y hasta donde nos dé tiempo estos 10 minutillos. 1155 01:41:14,760 --> 01:41:17,800 A lo mejor hasta nos da tiempo a, por lo menos, hacer un esbozo. 1156 01:41:25,130 --> 01:41:34,800 Mira, la clase File nos permite... 1157 01:41:34,800 --> 01:41:36,439 Mira, vamos a definirlo... 1158 01:41:37,659 --> 01:41:38,699 Vamos a poner aquí un string. 1159 01:41:38,699 --> 01:41:58,420 ese no un fich y hacia aquí en donde empieza el proyecto vamos a crear por ejemplo un fich un 1160 01:41:58,420 --> 01:42:05,819 directorio comando para crear un directorio de consola es el mkdir de inglés me director y 1161 01:42:07,399 --> 01:42:14,279 y vamos a poner aquí tenemos ahora esto un directorio si ponemos el s menos se lea para 1162 01:42:14,279 --> 01:42:19,520 que nos dé más detalles con el atributo lea el comando ls de linux vemos que 1163 01:42:19,520 --> 01:42:24,779 medir es efectivamente un directorio y que estos otros que tenemos por aquí 1164 01:42:24,779 --> 01:42:33,600 pues son ficheros lo indica aquí con un guioncito entonces vamos a poner a poner 1165 01:42:33,600 --> 01:42:42,500 un punto aquí no vamos a poner aquí vamos a empezar poniendo a medir que es 1166 01:42:42,500 --> 01:43:00,170 un directorio. Si yo cojo y digo aquí file, mi file igual a new file, aquí podría poner un string en 1167 01:43:00,170 --> 01:43:07,210 el constructor del file o un string que contenga o una variable de tipo string que contenga una 1168 01:43:07,210 --> 01:43:14,529 cadena de caracteres. Pues mi file nos permite validar cosas como por ejemplo estas. Podemos 1169 01:43:14,529 --> 01:43:25,770 decir mi file que es un objeto de la clase file que está referenciando a medir punto is es un 1170 01:43:25,770 --> 01:43:34,140 directorio es un fichero imaginaros que nos interesa es un es un fichero oculto vamos a 1171 01:43:34,140 --> 01:43:39,699 probar estas es un directorio es un directorio que nos devolvía nos devolvía entiendo si es una 1172 01:43:39,699 --> 01:43:47,039 pregunta, nos devuelve un boolean, es decir, true si es un directorio o false si no lo es. 1173 01:43:47,779 --> 01:43:53,079 Entonces, por ejemplo, podríamos aquí hacer una comprobación. En el contexto de un enunciado, 1174 01:43:53,199 --> 01:43:57,819 pues podríamos tener que validar en un momento dado si algo es un directorio o no es un directorio. 1175 01:43:59,399 --> 01:44:12,390 Lo podríamos comprobar así, diciendo, ¿es un directorio? Vamos a poner aquí un... 1176 01:44:12,390 --> 01:44:21,130 Y aquí podemos decir, ese nom es un directorio. 1177 01:44:26,279 --> 01:44:27,939 Voy a hacer un copy-paste de esto aquí. 1178 01:44:29,300 --> 01:44:34,560 Igual que estamos validando aquí si es un directorio, podríamos decir, is es un fichero. 1179 01:44:36,079 --> 01:44:38,960 De igual forma, aquí será true si es un fichero. 1180 01:44:39,399 --> 01:44:42,479 En este caso, midir hemos visto que no, que es un directorio. 1181 01:44:43,060 --> 01:44:46,420 Con lo cual, es previsible que aquí diga, es un directorio. 1182 01:44:46,420 --> 01:44:56,039 vamos a ponerlo aquí para el false, indicando 1183 01:44:56,039 --> 01:45:00,140 diciendo que no es un fichero 1184 01:45:00,140 --> 01:45:11,829 y aquí no es un directorio 1185 01:45:11,829 --> 01:45:15,869 entonces si hacemos una ejecución ahora, pues nos dice 1186 01:45:15,869 --> 01:45:20,510 es un directorio, no es un fichero, vale, pues lo previsible 1187 01:45:20,510 --> 01:45:24,130 mirad, aquí tenemos que fichlet es 1188 01:45:24,130 --> 01:45:28,189 un fichero, entonces si cogemos y en lugar de validar este 1189 01:45:28,189 --> 01:45:30,689 decimos que nos valide fichlet, pues nos dirá 1190 01:45:30,689 --> 01:45:35,310 no es un directorio, es un fichero. Bueno, pues un método que nos permite 1191 01:45:35,310 --> 01:45:38,789 comprobar una cosa o nos permite comprobar 1192 01:45:38,789 --> 01:45:45,600 otra. Otro de los métodos que tiene 1193 01:45:45,600 --> 01:46:00,670 punto exist. También nos dejó un boolean y dice 1194 01:46:00,670 --> 01:46:12,619 ¿existe o no existe? Existe, no existe. 1195 01:46:14,199 --> 01:46:16,239 Bueno, podría interesarnos en un momento dado. Dice 1196 01:46:16,239 --> 01:46:22,880 existe efectivamente y si aquí le decimos ese otro le añado un uno al nombre que ese ficherito no 1197 01:46:22,880 --> 01:46:32,079 existe pues dice no es un director no es un fichero y además no existe bueno métodos que están ahí 1198 01:46:32,079 --> 01:46:42,170 disponibles pues para poder utilizar en un momento dado aquí he vuelto a poner este fichlet si hacemos 1199 01:46:42,170 --> 01:46:55,720 aquí un ls aquí tenemos el fichlet.txt si hacemos una ejecución ahora mismo efectivamente nos dice 1200 01:46:55,720 --> 01:46:58,979 que es un fichero y que existe, pues bueno, otra de las opciones 1201 01:46:58,979 --> 01:47:01,840 que tenemos en la clase File 1202 01:47:01,840 --> 01:47:04,579 es mi file 1203 01:47:04,579 --> 01:47:07,760 punto, no sé si es remove o delete 1204 01:47:07,760 --> 01:47:10,619 pues no, delete 1205 01:47:10,619 --> 01:47:13,439 y esto que hace, pues nos borra un fichero, ¿qué fichero borra? 1206 01:47:13,920 --> 01:47:16,800 pues al que está apuntando, entonces si ahora hacemos un delete 1207 01:47:16,800 --> 01:47:20,079 aquí del fichero, pues luego no va a decir que no existe 1208 01:47:20,079 --> 01:47:27,750 porque lo va a borrar, ejecuto, ya me dice 1209 01:47:27,750 --> 01:47:34,229 que no existe por aquí y de hecho si nos venimos ahora ya aquí el fichero que era fichlet, veis 1210 01:47:34,229 --> 01:47:44,819 cómo se lo ha cargado, pues desde el programa podemos borrar un fichero. He entrado dentro del 1211 01:47:44,819 --> 01:47:50,119 directorio midir, este que había creado, proyecto directorio midir y vamos a hacer, vamos a crear 1212 01:47:50,119 --> 01:47:57,680 el comando touch en linux crea ficheros vacíos, los crea sin ninguna información pero ahí los 1213 01:47:57,680 --> 01:48:09,579 crea vale entonces vamos a llamarlo 1 punto txt vamos a hacer un touch de 2 sea un ls fijaros 1214 01:48:09,579 --> 01:48:15,220 cómo existen aquí estos dos ficheritos ahora me interesa que existan los ficheros sin información 1215 01:48:15,220 --> 01:48:22,199 por el momento por eso lo hecho con este comando todo mucho entonces ahora podemos decir que a este 1216 01:48:22,199 --> 01:48:40,600 directorio medir y a comentar todo este bloque que ya está visto podemos un listado de toda su 1217 01:48:40,600 --> 01:48:46,119 información y para ver el listado de su información lo que vamos a utilizar es 1218 01:48:46,119 --> 01:48:54,750 el método list el método list ponemos aquí mi file punto list fijaros que lo 1219 01:48:54,750 --> 01:49:00,029 que devuelve es un array de strings tiene sentido no nos va a devolver el 1220 01:49:00,029 --> 01:49:03,750 nombre de cada uno de los elementos que están en ese directorio como pueden ser 1221 01:49:03,750 --> 01:49:08,750 más de uno aquí tenemos en este caso tenemos dos en 1222 01:49:08,750 --> 01:49:15,310 este directorio, pues nos devuelve un array. Entonces para cargar la información en ese 1223 01:49:15,310 --> 01:49:22,770 array, lo que hacemos para cargar la información que tiene ese directorio, vamos por aquí, y nos 1224 01:49:22,770 --> 01:49:29,869 devuelve la información un array. Entonces definimos un string, ese info.dir, no me vale que sea un 1225 01:49:29,869 --> 01:49:37,489 string, necesito que sea un array de strings. Fijaros que no hacemos el new porque este método 1226 01:49:37,489 --> 01:49:43,560 ya se estará preocupando de hacerlo. Y ahora, bueno, esto no deja de ser 1227 01:49:43,560 --> 01:49:47,500 un array de strings que se habrá cargado con el contenido que tiene 1228 01:49:47,500 --> 01:49:51,359 el directorio donde en este momento está apuntando 1229 01:49:51,359 --> 01:49:55,600 file, que es midir. Sabemos, por otra parte, que tiene estos 1230 01:49:55,600 --> 01:49:59,140 dos elementos. Podríamos hacer un for, ¿verdad? 1231 01:49:59,140 --> 01:50:02,399 Para recorrer todos los elementos de un array. Decimos int i 1232 01:50:02,399 --> 01:50:06,199 igual a cero, mientras i sea menor 1233 01:50:06,199 --> 01:50:09,180 que el número de elementos que tiene el array 1234 01:50:09,180 --> 01:50:10,819 punto length 1235 01:50:10,819 --> 01:50:14,199 hacemos un y más más 1236 01:50:14,199 --> 01:50:29,729 aprovechamos con system.out.println 1237 01:50:29,729 --> 01:50:31,949 para recordar que es un flujo 1238 01:50:31,949 --> 01:50:32,949 de datos también 1239 01:50:32,949 --> 01:50:35,229 en este caso de salida del fichero 1240 01:50:35,229 --> 01:50:37,869 y escribimos el contenido del array 1241 01:50:37,869 --> 01:50:43,319 ahí lo tenemos, entonces si hacemos una ejecución 1242 01:50:43,319 --> 01:50:46,220 ahí lo tenéis 1243 01:50:46,220 --> 01:50:48,659 nos ha mostrado el listado de contenidos 1244 01:50:48,659 --> 01:50:49,300 que tiene 1245 01:50:49,300 --> 01:50:52,560 que conclusión llevamos, que file 1246 01:50:52,560 --> 01:51:03,960 lo que nos permite es hacer gestiones sobre elementos que tenemos en el sistema de archivos, 1247 01:51:03,960 --> 01:51:08,220 no tanto como para leer o escribir, que para eso tenemos un montón de clases por aquí, 1248 01:51:08,340 --> 01:51:14,300 sino para hacer otro tipo de gestiones con ellos, borrarlos, crearlos, eliminar un fichero. 1249 01:51:14,300 --> 01:51:23,960 otra de las opciones que tenemos fijaros vamos a hacerla es mi file punto mkdir para crear un 1250 01:51:23,960 --> 01:51:39,430 directorio crea el directorio este entonces vamos a decirle que cree el directorio dir nuevo perdón 1251 01:51:39,430 --> 01:51:47,470 claro esto el mkdir no lo podemos pasar aquí sino que lo que tenemos que hacer el directorio que 1252 01:51:47,470 --> 01:51:54,270 crea es el que tiene el file, vamos a crear un file, un nuevo file, mi file 2 y vamos a decir que el 1253 01:51:54,270 --> 01:52:12,579 directorio que queremos crear es un directorio que se llame hola, va a crear el directorio hola 1254 01:52:12,579 --> 01:52:23,680 en la ruta que tenemos por defecto, en principio será aquí, le damos aquí una ejecución, me ha dicho 1255 01:52:23,680 --> 01:52:29,500 el 1 y el 2 del otro sitio y ahora decimos aquí un ls y fijaros como tenemos ya el directorio hola 1256 01:52:29,500 --> 01:52:39,369 por aquí, a ver si ponemos aquí 1257 01:52:39,369 --> 01:52:46,640 punto barra, vamos a hacer esta prueba para ver si podemos crear el directorio 1258 01:52:46,640 --> 01:52:50,420 hola en el sitio donde nos encontramos en el proyecto 1259 01:52:50,420 --> 01:52:54,399 barra midir para intentar crear el directorio hola dentro de midir 1260 01:52:54,399 --> 01:52:58,760 que en este momento no existe, como podéis ver, le damos aquí una ejecución 1261 01:52:58,760 --> 01:53:03,760 y a ver si funciona, bueno, de hecho ha funcionado porque 1262 01:53:03,760 --> 01:53:07,699 ya el programa me lo está chivando aquí al hacer el recorrido del contenido de ese 1263 01:53:07,699 --> 01:53:15,319 directorio pues aquí una ls y veréis cómo ha creado el directorio hola por aquí también 1264 01:53:18,199 --> 01:53:24,180 y bueno nos ha quedado mucho la verdad de aquí quería contaros también cómo podíamos hacer para 1265 01:53:24,180 --> 01:53:29,000 a la hora de mostrar un listado file tienen bastante más opciones pero ahora demostrar un 1266 01:53:29,000 --> 01:53:32,539 listado se puede poner un filtro para que nos muestre todo el contenido pues sólo los que 1267 01:53:32,539 --> 01:53:39,800 tengan txt son los que empiecen por alguna forma existe una forma para hacer eso y que poder 1268 01:53:39,800 --> 01:53:45,479 generar un filtro sobre el contenido que nos devuelva list pero esto sí que lo dejamos ya 1269 01:53:45,479 --> 01:53:52,840 para arrancar la próxima tutoría y con eso y ya vamos a ver qué hacemos no sé si el plan de ver 1270 01:53:52,840 --> 01:53:57,239 los interfaces gráficos si no tenéis ninguna otra cosa por ahí que queréis que repasemos 1271 01:53:57,239 --> 01:54:04,560 ya terminamos la última tutoría la semana que viene alguna cosita antes de cerrar hoy que ya 1272 01:54:04,560 --> 01:54:41,560 son y media que nos estamos yendo de hora y van a venir los compis por aquí a ver vamos a ver 1273 01:54:41,560 --> 01:55:08,829 supongo rosa este enunciado cierto es a ver por dónde andamos desarrolló un programa luego no 1274 01:55:08,829 --> 01:55:14,250 estamos usando por ahí abajo que a ver la idea es leer lo que intenta plantear el enunciado es 1275 01:55:14,250 --> 01:55:21,689 lee el fichero usuarios y guarda su información podrías crear un array de strings pero lo que 1276 01:55:21,689 --> 01:55:27,390 te dice es que hagas pues un array de un array o que lo guardes no entiendo que será en un array 1277 01:55:27,390 --> 01:55:34,390 no me acuerdo ahora mismo de anunciado muy bien que lo guardes en como objeto de la clase usuario 1278 01:55:34,390 --> 01:55:45,869 que básicamente tienen el nombre no tiene más nombre y apellidos o sea esto estos nombres al 1279 01:55:45,869 --> 01:55:47,949 leer el fichero, los podría guardar en 1280 01:55:47,949 --> 01:55:48,949 un array de strings, ¿no? 1281 01:55:49,689 --> 01:55:51,590 Entonces, lo que te estoy diciendo aquí al enunciado es que 1282 01:55:51,590 --> 01:55:53,789 en lugar de un array de strings, pues 1283 01:55:53,789 --> 01:55:55,590 crees una clase de usuario, que 1284 01:55:55,590 --> 01:55:56,970 básicamente, no sé si 1285 01:55:56,970 --> 01:55:58,310 nos hace falta. 1286 01:55:59,289 --> 01:56:01,750 Sí, no sé si nos hace falta mucho más 1287 01:56:01,750 --> 01:56:03,810 por ahí. De tal forma, 1288 01:56:04,510 --> 01:56:07,609 también te digo que 1289 01:56:07,609 --> 01:56:09,689 si ves un diseño alternativo 1290 01:56:09,689 --> 01:56:11,689 y dices, pues mira, yo creo que es más 1291 01:56:11,689 --> 01:56:13,550 cómodo hacer lo que nos está pidiendo 1292 01:56:13,550 --> 01:56:15,770 directamente con lo que voy leyendo en un array 1293 01:56:15,770 --> 01:56:18,369 de strings, en lugar de crear una clase 1294 01:56:18,369 --> 01:56:21,489 usuario, pues en las prácticas hazlo, ¿sabes? 1295 01:56:21,829 --> 01:56:24,569 No te digo tanto que vayas tan 1296 01:56:24,569 --> 01:56:27,729 por libre en el examen, porque ahí sí que a lo mejor si ponemos, pues crea 1297 01:56:27,729 --> 01:56:30,909 un conjunto, una colección que sea de tipo conjunto 1298 01:56:30,909 --> 01:56:33,630 pues no me hagas una release, por ejemplo, ¿vale? Pero 1299 01:56:33,630 --> 01:56:36,489 aquí en las prácticas, al final, lo importante es practicar 1300 01:56:36,489 --> 01:56:39,670 entonces, bueno, pues igual esto está sobredimensionado, crear una 1301 01:56:39,670 --> 01:56:42,630 clase usuario, cuando realmente los usuarios solo tienen 1302 01:56:42,630 --> 01:56:44,670 un string, ¿no? Que pueda ser nombre y apellidos 1303 01:56:44,670 --> 01:56:47,109 pues si quieres implementarlo así, ¿sabes? 1304 01:56:47,130 --> 01:56:48,970 me pones si quieres un comentario ahí en la tarea 1305 01:56:48,970 --> 01:56:50,789 pues en lugar de crear una clase 1306 01:56:50,789 --> 01:56:52,569 he hecho esto, y si no, pues 1307 01:56:52,569 --> 01:56:54,949 si quieres crear la clase usuario que tenga simplemente 1308 01:56:54,949 --> 01:56:55,869 el atributo stream 1309 01:56:55,869 --> 01:56:58,310 que sea nombre y apellidos y ya está 1310 01:56:58,310 --> 01:57:05,060 vale, pues nada, pues ya cerramos 1311 01:57:05,060 --> 01:57:05,939 con esto por hoy 1312 01:57:05,939 --> 01:57:08,739 os sigo atendiendo por los foros 1313 01:57:08,739 --> 01:57:11,180 y la semana que viene nos vemos el lunes por aquí de nuevo