1 00:00:00,000 --> 00:00:06,860 Vale, estoy grabando, por lo tanto si habláis me autorizáis a grabar vuestra voz. 2 00:00:07,480 --> 00:00:12,660 Vamos a empezar hoy el concepto, a ver, unas pinceladas de persistencia de datos. 3 00:00:12,800 --> 00:00:19,019 En realidad la persistencia de datos se divide en dos grandes partes, digamos. 4 00:00:19,399 --> 00:00:27,280 Una es trabajar con ficheros y la otra sería la gestión, el acceso a las bases de datos. 5 00:00:27,280 --> 00:00:29,320 ¿Vale? El acceso a la base de datos 6 00:00:29,320 --> 00:00:31,559 Históricamente en esta asignatura 7 00:00:31,559 --> 00:00:33,380 Es la que dejamos al final 8 00:00:33,380 --> 00:00:35,020 Y si no nos da tiempo 9 00:00:35,020 --> 00:00:37,280 No pasa nada porque en segundo 10 00:00:37,280 --> 00:00:39,799 Tanto si hacéis DAM como si hacéis DAW 11 00:00:39,799 --> 00:00:41,719 Seguramente vais a 12 00:00:41,719 --> 00:00:43,659 Ver algo de acceso 13 00:00:43,659 --> 00:00:45,320 A base de datos desde 14 00:00:45,320 --> 00:00:47,399 Programación, por lo tanto no es una cosa 15 00:00:47,399 --> 00:00:49,359 Que hagas algo de aquí y no lo he visto nunca 16 00:00:49,359 --> 00:00:51,500 Además nosotros según 17 00:00:51,500 --> 00:00:55,100 Esto no lo debería grabar 18 00:00:56,060 --> 00:01:00,880 No lo grabo 19 00:01:00,880 --> 00:01:20,840 Vale, entonces, dos grandes áreas, no me acuerdo si le había dicho o no, ¿vale? Después de esta pausa que quién sabe qué se ha dicho. Pues, uno son los ficheros, la otra es la base de datos. Sí, le había dicho, ¿vale? Entonces, empezamos con conceptos un poco genéricos, luego vamos a ver, empezar un poquito cómo se usa un fichero y cómo se guarda el fichero. 20 00:01:20,840 --> 00:01:24,900 No es difícil, es bastante sencillo. 21 00:01:25,000 --> 00:01:33,079 Ahora, algunas cosas se pueden complicar, hay algunos peligros y problemas que surgen por allí. 22 00:01:34,159 --> 00:01:41,099 Tened en cuenta que nosotros llegaremos hasta un punto que será guardar objetos en un fichero, 23 00:01:41,659 --> 00:01:47,840 para que luego cuando lo necesitemos lo podemos volver a pillar, y esto no es lo que se hace hoy en día. 24 00:01:47,840 --> 00:02:05,480 Lo que vamos a aprender aquí es una base, es una idea básica que puede servir para mueblar nuestra cabeza, pero hoy en día nadie se soñaría en un proyecto serio de hacerlo como lo vamos a hacer nosotros. 25 00:02:05,480 --> 00:02:21,520 Hoy en día hay plugin, hay herramientas, hay mecanismos más avanzados que aprenderéis el próximo año o en los años siguientes de gestión de la cosa. 26 00:02:21,520 --> 00:02:41,300 Como por ejemplo, a lo mejor a alguien se os suena, Hibernate. Es una forma de gestionar la cosa. Tú tienes que configurar tu proyecto con varias cosas que no son triviales y una vez que lo has hecho, pues lo que haces es le dices a ellos, mira, guárdame estos ficheros y él lo guarda. 27 00:02:41,300 --> 00:02:42,960 ¿Vale? Pero hay que saber qué hacer. 28 00:02:43,180 --> 00:02:45,000 ¿Vale? Y entonces todavía es pronto. 29 00:02:45,400 --> 00:02:46,400 Pero sí, que 30 00:02:46,400 --> 00:02:48,840 lo que es guardar datos 31 00:02:48,840 --> 00:02:51,000 en ficheros y luego sacar ficheros 32 00:02:51,000 --> 00:02:52,560 de allí, pues sí que puede servir. 33 00:02:52,979 --> 00:02:54,900 ¿Vosotros no habéis visto, todavía me habéis dicho 34 00:02:54,900 --> 00:02:56,879 XML? ¿Vale? 35 00:02:57,099 --> 00:02:58,960 Pero, por ejemplo, lo que sí 36 00:02:58,960 --> 00:03:00,199 el XML 37 00:03:00,199 --> 00:03:02,919 es una cosa que 38 00:03:02,919 --> 00:03:05,060 que hay gente 39 00:03:05,060 --> 00:03:06,319 que la ama y hay gente que la odia. 40 00:03:06,780 --> 00:03:08,800 ¿Vale? Hay gente que dice la cosa peor 41 00:03:08,800 --> 00:03:10,919 que ha pasado la informática. Hay gente que 42 00:03:10,919 --> 00:03:17,039 dice no porque no se puede utilizar pero con lo que vemos ahora sí que se puede 43 00:03:17,039 --> 00:03:23,340 trabajar con xml que queriendo creando xml o leyendo xml por ahora dejando 44 00:03:23,340 --> 00:03:27,900 aquí aparcado lo veréis xml deberías empezar ahora porque tampoco queda 45 00:03:27,900 --> 00:03:37,659 mucho tiempo no vais a ver xml vais a ver xml casi seguramente porque es una 46 00:03:37,659 --> 00:03:43,180 parte importante de lenguaje de marcas o sea si habéis visto html pues igual html 47 00:03:43,180 --> 00:03:51,400 solo que te inventas las etiquetas y ya está hemos dado xml pues ya está vale el código 48 00:03:51,400 --> 00:03:58,060 programación orientado al objeto vale nosotros sabemos que es un objeto a este punto de nuestra 49 00:03:58,060 --> 00:04:09,780 vida sabemos cómo definimos un objeto como definimos un objeto con una clase vale definiendo 50 00:04:09,780 --> 00:04:16,019 una clase es una generalización de los objetos que luego voy a crear voy a definir los atributos los 51 00:04:16,019 --> 00:04:19,959 métodos que pueden, o sea, los comportamientos de estos objetos 52 00:04:19,959 --> 00:04:23,300 y por lo tanto para definir un objeto lo que se hace es definir 53 00:04:23,300 --> 00:04:27,620 su generalización, su abstracción, ¿vale? que sería la clase 54 00:04:27,620 --> 00:04:31,279 y luego a partir de ahí crea objetos concretos que podrán hacer 55 00:04:31,279 --> 00:04:35,660 lo que he establecido en la cosa, ¿vale? El código que yo 56 00:04:35,660 --> 00:04:39,720 escribo, compilado, etcétera, etcétera, se guarda normalmente 57 00:04:39,720 --> 00:04:46,990 ¿dónde? El código que yo escribo y que luego compilo 58 00:04:46,990 --> 00:04:49,350 en Java, etcétera, etcétera, ¿dónde se guarda? 59 00:04:51,850 --> 00:04:52,750 disco duro 60 00:04:52,750 --> 00:04:54,649 ¿vale? cosa interesante porque 61 00:04:54,649 --> 00:04:56,569 tú cuando escribes tu programa 62 00:04:56,569 --> 00:04:57,889 lo ejecutas 63 00:04:57,889 --> 00:05:00,589 le haces el Java C 64 00:05:00,589 --> 00:05:02,569 entonces obtienes el bytecode 65 00:05:02,569 --> 00:05:04,550 ¿vale? los puntos clases, cosas por el estilo 66 00:05:04,550 --> 00:05:05,709 esos 67 00:05:05,709 --> 00:05:08,589 ficheros, esa parte 68 00:05:08,589 --> 00:05:10,569 ese código no se pierde 69 00:05:10,569 --> 00:05:12,069 tú apagas el ordenador 70 00:05:12,069 --> 00:05:14,509 lo enciendes otra vez y ese código 71 00:05:14,509 --> 00:05:15,930 no se ha perdido 72 00:05:15,930 --> 00:05:18,629 ¿qué se pierde entonces entre apagar 73 00:05:18,629 --> 00:05:20,050 y encender el ordenador otra vez. 74 00:05:32,420 --> 00:05:33,839 Objetos y variables. 75 00:05:35,060 --> 00:05:37,699 Esos sí son los que estamos perdiendo ahora mismo. 76 00:05:38,100 --> 00:05:40,480 El código es el mismo, pero cada vez que lo enciendes 77 00:05:40,480 --> 00:05:42,480 como si empezaras desde cero. 78 00:05:42,920 --> 00:05:46,300 Si claramente en mi código hay una parte de inicialización 79 00:05:46,300 --> 00:05:49,300 que me crea 300 alumnos en código, 80 00:05:49,740 --> 00:05:51,660 que es una idea bastante fea, 81 00:05:51,660 --> 00:05:54,600 pero si lo hace, cada vez que lo arrancare 82 00:05:54,600 --> 00:05:56,660 me crearé estos 300 alumnos. 83 00:05:56,939 --> 00:05:59,819 Pero los objetos que estoy creando 84 00:05:59,819 --> 00:06:03,680 se están creando, ¿dónde? En la RAM. 85 00:06:03,839 --> 00:06:07,720 En particular en una área de la RAM, que es un trozo de la RAM 86 00:06:07,720 --> 00:06:11,819 que se dedica al proceso que yo estoy lanzando. Cuando yo ejecuto 87 00:06:12,339 --> 00:06:16,000 la Java Virtual Machine, será un proceso que es el intérprete 88 00:06:16,000 --> 00:06:20,000 y luego tendrá mi proceso, mi hilo de ejecución, que tendrá asociado 89 00:06:20,000 --> 00:06:23,920 un trozo de memoria. ¿Vale? Entre procesos no se 90 00:06:23,920 --> 00:06:27,879 comparte memoria. Entre threads sí. Es la diferencia que 91 00:06:27,879 --> 00:06:31,360 entre procesos y threads, y si queréis saber más, en segundo de DAM. 92 00:06:33,220 --> 00:06:39,620 Entonces, cuando yo creo objetos y variables, estos objetos y variables se guardan en RAM. 93 00:06:40,100 --> 00:06:45,139 La RAM es la memoria principal, la memoria más rápida, más cara también, 94 00:06:45,519 --> 00:06:50,199 pero tiene la cuestión de que si no tiene electricidad, todo lo que está en RAM se pierde. 95 00:06:50,560 --> 00:06:56,100 Entonces, entre una ejecución y otra, o entre un encendido y otro del ordenador, 96 00:06:56,100 --> 00:06:58,240 todo lo que estaba en la RAM, lo pierdo 97 00:06:58,240 --> 00:07:00,040 ¿vale? o sea que los datos 98 00:07:00,040 --> 00:07:01,819 en RAM no persisten 99 00:07:01,819 --> 00:07:03,860 para que persistan 100 00:07:03,860 --> 00:07:06,180 tengo que utilizar el disco 101 00:07:06,180 --> 00:07:07,860 duro, ahora vosotros sabéis 102 00:07:07,860 --> 00:07:10,000 de sistemas informáticos que la RAM 103 00:07:10,000 --> 00:07:12,199 va rápida y es bonita, pues el disco 104 00:07:12,199 --> 00:07:14,199 duro es súper lento, cada vez que toco 105 00:07:14,199 --> 00:07:15,959 el disco duro 106 00:07:15,959 --> 00:07:17,519 ralentizo muchísimo 107 00:07:17,519 --> 00:07:19,779 mi programa 108 00:07:19,779 --> 00:07:22,180 de hecho, si vosotros tenéis 109 00:07:22,180 --> 00:07:23,899 poca RAM en vuestro ordenador 110 00:07:23,899 --> 00:07:25,540 y encendéis varios 111 00:07:25,540 --> 00:07:28,540 programas, el navegador 112 00:07:28,540 --> 00:07:30,060 luego un juego, luego no sé qué 113 00:07:30,060 --> 00:07:32,279 llega un momento en que todo va súper lento 114 00:07:32,279 --> 00:07:33,399 ¿por qué va todo súper lento? 115 00:07:47,980 --> 00:07:50,100 porque yo necesito trabajar 116 00:07:50,100 --> 00:07:52,759 los programas trabajan con la RAM pero no hay suficiente 117 00:07:52,759 --> 00:07:54,399 RAM para todos y entonces 118 00:07:54,399 --> 00:07:58,560 los procesadores normalmente 119 00:07:58,560 --> 00:08:00,480 hoy en día hacen lo que se llama programación 120 00:08:00,480 --> 00:08:02,100 concurrente, o sea que 121 00:08:02,100 --> 00:08:04,819 hay pocos recursos de procesamiento 122 00:08:04,819 --> 00:08:06,480 un procesador con 123 00:08:06,480 --> 00:08:08,500 cuatro núcleos 124 00:08:08,500 --> 00:08:14,220 por ejemplo, pues eso quiere decir que puedo ejecutar cuatro hilos, cuatro hilos de ejecución 125 00:08:14,220 --> 00:08:19,300 en cada momento. Ocho si tengo multitrading que hace cosas raras, pero me da igual. O 126 00:08:19,300 --> 00:08:23,120 dieciséis si tengo un procesador más potente. Pero la cuestión es que eso son los que se 127 00:08:23,120 --> 00:08:28,199 pueden ejecutar. Ahora, ¿qué pasa? El procesador los va cambiando constantemente, uno y otro, 128 00:08:28,319 --> 00:08:34,559 uno y otro, dándome la ilusión que estén viendo todos a la vez. Pero en realidad, paralelismo 129 00:08:34,559 --> 00:08:37,779 verdadero, pues solo lo puede hacer con muy pocos 130 00:08:37,779 --> 00:08:40,820 procesos, con muy pocos threads, porque son los threads 131 00:08:40,820 --> 00:08:43,740 que tengan los núcleos que puede ejecutar 132 00:08:43,740 --> 00:08:46,820 ¿vale? Ahora, si no tengo RAM suficiente 133 00:08:46,820 --> 00:08:49,600 cada vez que un proceso llega al procesador 134 00:08:49,600 --> 00:08:52,720 y tiene que ser ejecutado, quiere encontrarse los datos 135 00:08:52,720 --> 00:08:55,759 en la RAM, pero si no hay espacio para todos 136 00:08:55,759 --> 00:08:59,000 el sistema operativo empieza a hacer operaciones de swapping 137 00:08:59,000 --> 00:09:01,559 o sea, pillo lo que está en la RAM 138 00:09:01,559 --> 00:09:05,039 Libero una parte de la RAM de otro proceso 139 00:09:05,039 --> 00:09:07,100 Que en este momento no se está ejecutando 140 00:09:07,100 --> 00:09:08,740 Y lo copio en el disco duro 141 00:09:08,740 --> 00:09:12,399 Voy a pillar lo que había copiado tuyo en el disco duro 142 00:09:12,399 --> 00:09:13,559 Y lo copio en RAM 143 00:09:13,559 --> 00:09:15,620 Y esto se está haciendo constantemente 144 00:09:15,620 --> 00:09:18,539 Ahora como el disco duro es lento 145 00:09:18,539 --> 00:09:20,980 Pues todo empieza a ir muy muy lento 146 00:09:20,980 --> 00:09:23,000 Porque cada vez que hago esta operación de swapping 147 00:09:23,000 --> 00:09:25,039 Pues esto es muy lentísimo 148 00:09:25,039 --> 00:09:26,320 ¿Sí? 149 00:09:27,320 --> 00:09:27,580 Vale 150 00:09:27,580 --> 00:09:34,919 Entonces, también el código que yo ejecuto se guarda en RAM 151 00:09:34,919 --> 00:09:37,720 O sea, eso está guardado en el disco duro 152 00:09:37,720 --> 00:09:40,220 Pero cuando ejecuto al principio el programa 153 00:09:40,220 --> 00:09:44,840 Copio desde disco duro las instrucciones a RAM 154 00:09:44,840 --> 00:09:47,759 Porque luego cuando se ejecuta RAM tiene que estar en RAM 155 00:09:47,759 --> 00:09:51,679 Y luego todos los niveles de caché que vosotros conocéis 156 00:09:51,679 --> 00:09:53,679 Siempre más cerca del procesador 157 00:09:53,679 --> 00:09:56,360 Hasta llegar a la memoria más pequeña y más rápida 158 00:09:56,360 --> 00:09:58,500 que son los registros del procesador 159 00:09:58,500 --> 00:09:58,960 ¿sí? 160 00:10:00,299 --> 00:10:02,299 entonces, hemos dicho que nuestros 161 00:10:02,299 --> 00:10:04,519 objetos en estas variables no persisten 162 00:10:04,519 --> 00:10:05,759 se acaban, ¿vale? 163 00:10:07,120 --> 00:10:08,519 los valores de atributos 164 00:10:08,519 --> 00:10:10,759 de los objetos no persisten previamente en el disco 165 00:10:10,759 --> 00:10:12,600 ¿vale? cuando hago una new 166 00:10:12,600 --> 00:10:14,039 se crea un nuevo 167 00:10:14,039 --> 00:10:16,679 en un trozo de la rama, un nuevo objeto 168 00:10:16,679 --> 00:10:18,399 y este trozo de la rama 169 00:10:18,399 --> 00:10:19,539 se llama heap 170 00:10:19,539 --> 00:10:21,960 mucio, ¿vale? 171 00:10:22,179 --> 00:10:24,080 no, mucio es italiano, montón 172 00:10:24,080 --> 00:10:25,500 es español, ¿sí? 173 00:10:26,360 --> 00:10:30,779 los objetos se crean en esta zona 174 00:10:30,779 --> 00:10:33,100 porque es una zona que funciona un poquito distinta 175 00:10:33,100 --> 00:10:35,460 con como se crean en vez de las variables 176 00:10:35,460 --> 00:10:36,980 que es otra zona que ahora vemos 177 00:10:36,980 --> 00:10:41,759 y entonces no tiene el mismo funcionamiento que el otro 178 00:10:41,759 --> 00:10:45,460 no sabría definiros bien 179 00:10:45,460 --> 00:10:51,860 como funciona el heap de Java 180 00:10:51,860 --> 00:10:54,860 sepáis simplemente que es otro tipo de 181 00:10:54,860 --> 00:10:57,340 estructura datos dinámica 182 00:10:57,340 --> 00:10:58,879 ¿vale? no es 183 00:10:58,879 --> 00:11:00,919 una cola, no es una pila 184 00:11:00,919 --> 00:11:02,700 no es una lista 185 00:11:02,700 --> 00:11:04,899 es otra forma de organizar 186 00:11:04,899 --> 00:11:06,720 los datos allí, con muchas referencias 187 00:11:06,720 --> 00:11:08,759 porque vosotros sabéis que los objetos tienen 188 00:11:08,759 --> 00:11:10,240 toda esta cosa de referencias 189 00:11:10,240 --> 00:11:11,840 etcétera, etcétera, ¿vale? 190 00:11:12,059 --> 00:11:14,679 por otro lado, en vez de las variables locales 191 00:11:14,679 --> 00:11:16,720 los parámetros, cuando llamo un método 192 00:11:16,720 --> 00:11:18,600 y cosas por el estilo, se guardan en una zona 193 00:11:18,600 --> 00:11:20,639 de memoria que se llama la stack 194 00:11:20,639 --> 00:11:22,419 ¿vale? que es esta pila 195 00:11:22,419 --> 00:11:24,220 y vosotros sabéis que es una pila, ¿vale? 196 00:11:24,220 --> 00:11:44,000 Entonces, cuando nosotros, ¿os acordáis el concepto que vimos al principio de curso de ámbito de una variable? El scope, ¿vale? Que una variable solo existe en el bloque en el que la declaro, ¿vale? Y muchas veces los bloques se relacionan también con métodos. 197 00:11:44,000 --> 00:12:03,340 O sea, un método al fin y al cabo es un bloque. Yo llamo desde aquí y cosas por el estilo. Entonces existe esta pila que sustancialmente va apilando las nuevas llamadas de métodos o los nuevos bloques que se crean y allí en cada nivel de la pila crea las variables. 198 00:12:03,340 --> 00:12:18,200 De esta forma que cuando se acaba un bloque, entonces todas las variables que estaban en ese nivel de la pila, se hace una pop en la pila, se quita la cabeza de la pila y todas esas variables ya no existen. 199 00:12:18,279 --> 00:12:20,779 Es la razón de por qué existen las variables locales. 200 00:12:21,179 --> 00:12:31,100 Tú dentro del bloque las declaras, declaras dentro de un for una int i, usas i todo lo que te da la gana dentro del for, pero cuando sale del for ya i no existe. 201 00:12:31,100 --> 00:12:41,100 Si la necesito fuera de IMET, la tengo que guardar en algún lado o declararla fuera del FOR para que valga en el nivel más bajo de la pila. 202 00:12:41,799 --> 00:12:42,120 ¿Se entiende? 203 00:12:43,399 --> 00:12:43,679 Vale. 204 00:12:44,019 --> 00:12:46,419 Entonces, todo esto a nivel de RAM. 205 00:12:46,840 --> 00:12:50,620 Cuando apago, enciendo o acabo la ejecución, se pierde todo. 206 00:12:50,899 --> 00:12:51,039 ¿Vale? 207 00:12:51,980 --> 00:12:57,759 Cuando finaliza el programa, los datos de los atributos del IP y también algunos de los TAC, pues, no persisten. 208 00:12:57,879 --> 00:12:58,059 ¿Vale? 209 00:12:58,059 --> 00:13:00,059 Aunque en muchos casos sería deseable. 210 00:13:00,960 --> 00:13:01,080 ¿Vale? 211 00:13:01,100 --> 00:13:23,659 Lo que hemos hecho siempre, por ejemplo, con el alumno, pero puede ser con cliente, puede ser con coche, todo lo que yo he creado. Imaginaos las cosas que estáis haciendo ahora con Graphical User Interface, que ponéis los datos y los grabáis. Pues estáis creando cosas. No quiero que cada mañana que empiece a trabajar en mi empresa tenga que volver a grabar todos los datos de los clientes para poder trabajar con ellos. 212 00:13:23,659 --> 00:13:26,480 entonces, no se existe 213 00:13:26,480 --> 00:13:28,100 un mecanismo 214 00:13:28,100 --> 00:13:30,279 automático de persistencia 215 00:13:30,279 --> 00:13:32,240 en la mayoría de los lenguajes 216 00:13:32,240 --> 00:13:34,320 de un reto de objetos, en particular 217 00:13:34,320 --> 00:13:36,580 en Java, no existe algo 218 00:13:36,580 --> 00:13:38,220 automático que dice 219 00:13:38,220 --> 00:13:40,279 si ahora se va la luz, pues estaba 220 00:13:40,279 --> 00:13:42,240 guardando todo en el disco duro y no he perdido 221 00:13:42,240 --> 00:13:44,000 nada, lo tengo que hacer yo 222 00:13:44,000 --> 00:13:46,179 manualmente, en el sentido, no 223 00:13:46,179 --> 00:13:48,220 necesariamente soy yo el que va a escribir 224 00:13:48,220 --> 00:13:50,120 ceros y unos con un 225 00:13:50,120 --> 00:13:51,820 imán en el disco duro 226 00:13:51,820 --> 00:14:04,799 ¿Vale? Pero si soy yo que le tengo que decir en un determinado momento, este es el momento en el que tu programa, haz tu magia y guárdame estos datos que te paso en un fichero. 227 00:14:05,440 --> 00:14:12,279 ¿Sí? Si los guardo bien y lo hago bien, mañana cuando enciende mi ordenador, pues posiblemente siguen allí. 228 00:14:12,279 --> 00:14:28,340 Si lo has escrito en formato texto, los puedo hasta mirar yo. Si lo he escrito de otro formato, puedo ir a mirar, pero veré estas cosas raras que hace alguna vez cuando abrís un fichero con el Notepad y hay carácteres que no son texto, ¿vale? 229 00:14:28,340 --> 00:14:41,340 Entonces, dependiendo de allí, ahora lo veremos también, nosotros podremos escribir en fichero y decidir si escribimos bytes, entonces puede ser cualquier cosa, o si escribimos caracteres. 230 00:14:42,259 --> 00:14:48,899 Entonces ya tengo algunas limitaciones porque estoy escribiendo caracteres y no cualquier cosa como un byte o cosa por el estilo. 231 00:14:48,899 --> 00:15:12,139 Si estoy copiando y trabajando con ficheros de textos, utilizaré char y string y lo que sea, si los ficheros con los que estoy trabajando no están pensados para ser inteligibles, para ser humanos, entonces no son de tipo texto, pues debería trabajar con bytes. 232 00:15:12,139 --> 00:15:21,679 porque si no, podría ser que un char no se corresponda exactamente a los bytes que estoy leyendo. 233 00:15:21,940 --> 00:15:26,139 Y entonces podría ser que cuando voy a leer, yo leo en grupos para traducirlos en char, 234 00:15:26,500 --> 00:15:32,539 y pues un grupo se queda en mitad porque allí acababa el byte o acababan los ficheros que estaba mirando. 235 00:15:32,960 --> 00:15:37,659 Un ejemplo de ficheros que no utilizan cosas son los ejecutables. 236 00:15:37,659 --> 00:15:52,080 Todos los ficheros que son .exe, si vosotros intentáis abrirlos con un bloc de notas, pues veis que no se entiende porque esos son ceros y unos que se interpretarán por el procesador. 237 00:15:52,740 --> 00:16:01,399 Entonces, no son caracteres. Entonces, cuando lo voy a interpretar, el bloc de notas intenta interpretarlo como caracteres, salen cosas raras. 238 00:16:01,399 --> 00:16:05,740 almacenamiento de datos 239 00:16:05,740 --> 00:16:08,100 ¿cómo conservamos valores de datos 240 00:16:08,100 --> 00:16:10,059 en un dispositivo de almacenamiento 241 00:16:10,059 --> 00:16:12,480 y cosas por el estilo? pues hay varias opciones 242 00:16:12,480 --> 00:16:14,480 ¿vale? opción número A 243 00:16:14,480 --> 00:16:16,100 creando un archivo 244 00:16:16,100 --> 00:16:18,139 ¿vale? que es lo que veremos nosotros 245 00:16:18,139 --> 00:16:20,179 entonces nosotros tenemos en nuestro oficiero 246 00:16:20,179 --> 00:16:22,460 le guardamos los datos en modo 247 00:16:22,460 --> 00:16:24,279 RAW, en modo crudo 248 00:16:24,279 --> 00:16:26,259 en modo tal cual son 249 00:16:26,259 --> 00:16:28,440 ¿vale? lo guarda allí o en modo texto 250 00:16:28,440 --> 00:16:29,799 ¿vale? o en 251 00:16:29,799 --> 00:16:31,740 Voy a copiar los ceros y unos 252 00:16:31,740 --> 00:16:33,200 Que será este objeto 253 00:16:33,200 --> 00:16:35,519 Al fin y al cabo todo en informática son ceros y unos 254 00:16:35,519 --> 00:16:37,039 Entonces yo puedo 255 00:16:37,039 --> 00:16:38,980 Trabajar con ceros y unos 256 00:16:38,980 --> 00:16:40,159 Que sería el modo row 257 00:16:40,159 --> 00:16:43,379 Y entonces mi objeto será una tira de ceros y unos 258 00:16:43,379 --> 00:16:45,399 Pues copio estos ceros y unos en un fichero 259 00:16:45,399 --> 00:16:47,820 Pues ya está, tengo mi objeto guardado 260 00:16:47,820 --> 00:16:50,720 O si no, en modo texto 261 00:16:50,720 --> 00:16:52,659 Veremos los dos ejemplos 262 00:16:52,659 --> 00:16:56,059 También puedo tirar de la Java Virtual Machine 263 00:16:56,059 --> 00:16:57,360 Y decir, Java Virtual Machine 264 00:16:57,360 --> 00:16:59,460 Mira, yo te doy un fichero 265 00:16:59,460 --> 00:17:15,119 Luego te doy un objeto, guárdamelo tú. Haz tu magia, haz lo que tienes que hacer. Yo no quiero saber cómo lo guardas, qué estás haciendo por debajo. Estoy abstraendo el cómo se hace, te estoy diciendo qué hacer. 266 00:17:15,119 --> 00:17:40,119 Entonces, tengo este objeto, por favor guárdamelo tú, ¿vale? No todos los objetos se pueden guardar, hay características que tengo que tener en cuenta y cuidado porque la cosa se puede complicar, ¿vale? Esto se llama normalmente la serialización de un objeto, transformar un objeto en una serie de ceros y unos que pasaré al disco duro y que lo guardaré allí, ¿vale? 267 00:17:40,119 --> 00:17:44,680 Veremos que para que un objeto sea guardado en un disco duro 268 00:17:44,680 --> 00:17:46,759 Tiene que implementar la interfaz 269 00:17:46,759 --> 00:17:48,839 Serializable 270 00:17:48,839 --> 00:17:51,140 Serializable 271 00:17:51,140 --> 00:17:52,759 No sé cómo se pronuncia 272 00:17:52,759 --> 00:17:53,000 ¿Vale? 273 00:17:54,619 --> 00:17:56,380 Otra opción es 274 00:17:56,380 --> 00:17:59,500 Molestar a las bases de datos 275 00:17:59,500 --> 00:18:00,000 ¿Vale? 276 00:18:00,099 --> 00:18:01,420 Entonces decir a las bases de datos 277 00:18:01,420 --> 00:18:04,819 Oye, mira, como son muchos datos los que tengo que gestionar 278 00:18:04,819 --> 00:18:07,660 Y el disco duro no está optimizado para esto 279 00:18:07,660 --> 00:18:11,039 voy a buscar a alguien que está especializado en guardar datos 280 00:18:11,039 --> 00:18:14,200 y le digo, oye, mira, guárdame estas cosas, ¿vale? 281 00:18:14,339 --> 00:18:17,480 A partir de allí se puede guardar de distintas formas, 282 00:18:17,980 --> 00:18:22,380 como en unas tablas que tenga columnas distintas 283 00:18:22,380 --> 00:18:25,220 y por cada columna tenga un atributo del objeto 284 00:18:25,220 --> 00:18:27,880 y que yo guarde allí en cada columna su objeto, 285 00:18:28,339 --> 00:18:30,980 o pueda utilizar un blob o lo que sea 286 00:18:30,980 --> 00:18:34,619 para guardar enteros los objetos por ahí, ¿vale? 287 00:18:34,619 --> 00:18:38,700 si necesito mucho esto 288 00:18:38,700 --> 00:18:41,980 entonces tengo programas que necesitan guardar 289 00:18:41,980 --> 00:18:43,920 y recuperar muchos de estos 290 00:18:43,920 --> 00:18:47,559 objetos, pues posiblemente montaré 291 00:18:47,559 --> 00:18:50,720 algunos de estos mecanismos como Evernate o cosas por el estilo 292 00:18:50,720 --> 00:18:53,059 que me permite trabajar con 293 00:18:53,059 --> 00:18:55,759 la base de datos y hacerlo rápidamente 294 00:18:55,759 --> 00:18:58,859 nosotros por ahora no 295 00:18:58,859 --> 00:19:02,759 vale, entonces empezamos a ver que nos hace falta 296 00:19:02,759 --> 00:19:07,440 para poder trabajar con Java y hacer cosas con ficheros? 297 00:19:07,539 --> 00:19:09,660 Pues la primera es la clase File, ¿vale? 298 00:19:10,039 --> 00:19:14,460 Existe la clase File que ya existe en java.io, ¿vale? 299 00:19:14,539 --> 00:19:17,599 Paquete de input-output, ¿vale? 300 00:19:17,819 --> 00:19:24,160 Entonces es una clase que abstrae y representa un fichero. 301 00:19:24,160 --> 00:19:28,759 Cuidado, no es un fichero, es un manejador de fichero, ¿se entiende? 302 00:19:28,759 --> 00:19:31,440 Es como a nivel de Java 303 00:19:31,440 --> 00:19:35,440 Puedo referenciar un fichero 304 00:19:35,440 --> 00:19:37,319 Luego el fichero estará en el disco duro 305 00:19:37,319 --> 00:19:38,259 Y será otra cosa 306 00:19:38,259 --> 00:19:40,400 Pero si yo tengo que saber 307 00:19:40,400 --> 00:19:42,839 Por ejemplo, preguntarme cosas como 308 00:19:42,839 --> 00:19:44,519 Si este fichero ya existe 309 00:19:44,519 --> 00:19:47,559 Si este fichero tiene dentro datos 310 00:19:47,559 --> 00:19:48,380 O cosas por el estilo 311 00:19:48,380 --> 00:19:51,420 Necesito un handler, un manejador 312 00:19:51,420 --> 00:19:53,119 Desde la perspectiva de Java 313 00:19:53,119 --> 00:19:54,039 Para poder decir 314 00:19:54,039 --> 00:19:56,839 Este es un objeto que representa este fichero 315 00:19:56,839 --> 00:20:02,900 ahora te hago preguntas a ti objeto y tú harás lo que sea para ir a mirar en el disco duro 316 00:20:02,900 --> 00:20:07,079 si efectivamente estas cosas son verdaderas, son falsas, cuánto ocupas, etc. 317 00:20:08,039 --> 00:20:17,920 El punto, es siempre lo que hacemos en Java al fin y al cabo, es intentar extraer cosas más o menos físico-reales. 318 00:20:18,579 --> 00:20:21,880 Nosotros no queremos trabajar directamente con los discos duros y decirle 319 00:20:21,880 --> 00:20:28,259 ponte a girar o ponte a buscar niveles de energía de donde has guardado en el SSD el fichero, 320 00:20:28,359 --> 00:20:32,799 pues no me interesa, pues a mí me interesa extraer, decirle, oye, mira, esto es un fichero, vale, 321 00:20:33,019 --> 00:20:35,759 ahora represento un fichero, usámoslo, ¿vale? 322 00:20:36,319 --> 00:20:41,119 Para crear o abrir un fichero, en Java se invoca un constructor de la clase File, ¿vale? 323 00:20:41,259 --> 00:20:44,720 Entonces yo creo un new file y ese de allí me crea ya el constructor. 324 00:20:44,720 --> 00:20:50,099 Si quiero estar seguro que exista, está también una función de create file, si no existe, 325 00:20:50,099 --> 00:21:12,319 Y existe un otro método que es el exists, que me devuelve true si el fichero ya existe y false si no, ¿vale? Entonces, una cosa estándar es crear el fichero como objeto, comprobar si ya existe, si ya existe lo utilizo, si no existe lo creo o lo relleno o doy un error, dependiendo de lo que quiero hacer, ¿vale? 326 00:21:12,319 --> 00:21:30,000 Si estoy haciendo un programa donde está una serie de datos de inicialización, entonces tengo un fichero de init donde dentro pongo los datos iniciales de mi programa y este fichero no está, podría simplemente decir, oye, mira, tengo un problema, no existe el fichero init. 327 00:21:30,000 --> 00:22:02,279 Si os acordáis, no nos ha pasado a nosotros un error cuando Manoli instaló la base de datos, nuestro programa Eclipse dejó de funcionar y que había que buscar un fichero .ini y cambiarle la cosa allí, que .ini de inicialización, porque allí no encontraba la Java Virtual Machine correcta. 328 00:22:02,839 --> 00:22:21,880 ¿No? ¿Sí? ¿Pasado este año? Pues yo creo que sí, pero no me acuerdo. Vale, entonces, una vez que tengo el fichero file, pues necesito trabajar con flujos de información, streams, ¿vale? Y tengo input stream y output stream. 329 00:22:21,880 --> 00:22:31,779 Los output stream son los que escriben en el fichero, los input stream son los que leen de fichero. 330 00:22:31,980 --> 00:22:42,220 La perspectiva es de mi programa, ¿vale? Entonces si yo estoy en mi programa, lo que es output es cosas que salen de mi programa y van fuera de mi programa, por ejemplo en un fichero. 331 00:22:42,700 --> 00:22:48,119 Input son cosas que están fuera de mi programa y yo quiero leer para introducirlos en mi programa. 332 00:22:48,119 --> 00:23:08,039 Entonces, cuando yo quiero salvar los datos, necesitaré un output stream para poder escribir los datos en memoria secundaria. Cuando enciendere mi programa otra vez y será un programa nuevo y quiere leer esos datos, necesitaré un input stream para poder leer desde ese lado. 333 00:23:08,039 --> 00:23:23,819 ¿Se entiende más o menos? El input stream es el más, y output stream son los niveles más bajos que podáis encontrar en Java. Si hurgáis, pues encontráis cosas más bajas, pero lo que usamos nosotros. 334 00:23:23,819 --> 00:23:41,119 Es decir, que son los que están más cercanos a los ceros y unos, a los bytes que quiero leer. Por eso, las funciones que me proporciona InputStream y OutputStream son funciones de bajo nivel. 335 00:23:41,119 --> 00:23:47,259 de escríbeme este byte en el fichero, léeme un byte, ¿vale? 336 00:23:47,259 --> 00:23:49,839 Estamos trabajando con byte, no estamos trabajando con string, 337 00:23:49,940 --> 00:23:51,259 no estamos trabajando con objetos. 338 00:23:51,759 --> 00:23:54,539 Se lee byte por byte, se escribe byte por byte. 339 00:23:54,900 --> 00:23:58,380 Y vosotros podéis hacer absolutamente todo a este nivel. 340 00:23:59,240 --> 00:24:01,039 Ahora, ¿cómo es aburrido? 341 00:24:01,660 --> 00:24:05,660 Porque, por ejemplo, si tú lees un entero, en vez de leer un entero, 342 00:24:05,660 --> 00:24:09,640 deberías leer cuatro bytes y luego mezclar los estos bytes 343 00:24:09,640 --> 00:24:11,279 y hacer un único entero grande 344 00:24:11,279 --> 00:24:13,019 y a ese punto interpretarlo como un entero 345 00:24:13,019 --> 00:24:15,559 si es un double son 8, si es un char 346 00:24:15,559 --> 00:24:17,259 no lo sé, son 2, 1, cuánto es 347 00:24:17,259 --> 00:24:19,400 pues sería complejo 348 00:24:19,400 --> 00:24:21,160 pues hay 349 00:24:21,160 --> 00:24:22,440 clases 350 00:24:22,440 --> 00:24:25,380 que van subiendo el nivel 351 00:24:25,380 --> 00:24:27,500 de abstracción que me crean 352 00:24:27,500 --> 00:24:28,420 nuevos 353 00:24:28,420 --> 00:24:31,700 métodos que se puedan 354 00:24:31,700 --> 00:24:33,619 utilizar para sostancialmente 355 00:24:33,619 --> 00:24:35,059 en vez de trabajar byte por byte 356 00:24:35,059 --> 00:24:36,759 trabajar con cosas un poquito más 357 00:24:36,759 --> 00:24:38,799 fáciles para los seres humanos 358 00:24:38,799 --> 00:25:01,039 Entonces, InputStream encapsula un flujo de bits para leer, que pueden provenir del teclado, de un fichero, de una conexión de red, etc. El escáner probablemente por dentro tiene un InputStream o parecido, que lo que hace es leer la información que llega desde el teclado. 359 00:25:01,039 --> 00:25:04,339 Pero para nosotros es una abstracción y nosotros no lo vemos. 360 00:25:04,759 --> 00:25:06,559 No hemos creado InputStream, pero será. 361 00:25:07,380 --> 00:25:13,759 La cosa interesante es que con InputStream tú lees desde cual sea la fonte que llegas. 362 00:25:14,079 --> 00:25:16,000 Este año lo usamos para ficheros. 363 00:25:16,000 --> 00:25:21,859 Si llegáis en segundo de DAM, pues lo usaremos para conexiones de red para los sockets. 364 00:25:22,539 --> 00:25:26,140 Y es lo mismo. Es exactamente esta misma clase. 365 00:25:26,559 --> 00:25:27,640 Tanto aquí como allá. 366 00:25:27,640 --> 00:25:32,359 Es simplemente una clase que me permite leer bytes y guardarlos en una red de bytes. 367 00:25:33,619 --> 00:25:41,940 Ahora, si no quiero trabajar con bytes, ¿por qué lo que estoy trabajando son mensajes de texto? 368 00:25:42,079 --> 00:25:44,880 ¿Por qué los ficheros que estoy utilizando son ficheros de texto? 369 00:25:45,059 --> 00:25:56,720 ¿Por qué no estoy trabajando con ficheros que no son inteligibles para los seres humanos? 370 00:25:56,720 --> 00:26:00,980 y por lo tanto necesito que sean interpretados como carácteres, 371 00:26:00,980 --> 00:26:06,660 en vez de utilizar un inputStream, podría utilizar un inputStreamReader. 372 00:26:07,079 --> 00:26:13,759 Cuando está la palabra reader o writer, es que no estoy trabajando byte por byte, 373 00:26:14,059 --> 00:26:16,839 sino que estoy trabajando con char, con carácteres. 374 00:26:17,700 --> 00:26:22,240 Si tiene este reader, tiene esta funcionalidad extra. 375 00:26:22,240 --> 00:26:23,839 Como yo asumo 376 00:26:23,839 --> 00:26:26,099 Que ahora no estoy trabajando byte con byte 377 00:26:26,099 --> 00:26:28,019 Pero asumo que estos sean caracteres 378 00:26:28,019 --> 00:26:30,259 Puedo crear 379 00:26:30,259 --> 00:26:31,980 Nuevos metodillos 380 00:26:31,980 --> 00:26:34,279 Que ya asuman esto 381 00:26:34,279 --> 00:26:36,099 Que ya digan, ah vale, cuando leo 382 00:26:36,099 --> 00:26:37,559 No voy a leer un byte 383 00:26:37,559 --> 00:26:39,079 Sé que voy a leer un char 384 00:26:39,079 --> 00:26:42,220 Por lo tanto, la respuesta al read 385 00:26:42,220 --> 00:26:44,240 No será que te devuelvo 386 00:26:44,240 --> 00:26:45,619 Un array de byte 387 00:26:45,619 --> 00:26:47,680 A lo mejor te devuelvo un array de char 388 00:26:47,680 --> 00:26:49,539 ¿Vale? Teniendo en cuenta que 389 00:26:49,539 --> 00:26:52,019 De todas formas, un array stream reader 390 00:26:52,019 --> 00:26:53,720 un inputStreamReader como veremos 391 00:26:53,720 --> 00:26:55,880 como parámetro del 392 00:26:55,880 --> 00:26:58,140 constructor pilla un inputStream 393 00:26:58,140 --> 00:26:59,900 o sea que es sustancialmente 394 00:26:59,900 --> 00:27:02,339 un involucrar 395 00:27:02,339 --> 00:27:03,460 un rapear 396 00:27:03,460 --> 00:27:06,000 no lo sé como decirlo 397 00:27:06,000 --> 00:27:09,700 pillar algo que solo 398 00:27:09,700 --> 00:27:11,779 tiene metodillos básicos de leer byte por 399 00:27:11,779 --> 00:27:13,579 byte y decir vale te extendo 400 00:27:13,579 --> 00:27:15,920 en un cierto sentido, no es una extensión 401 00:27:15,920 --> 00:27:17,400 en términos de 402 00:27:17,400 --> 00:27:19,619 herencia pero por ahí 403 00:27:19,619 --> 00:27:21,680 voy a hacer cosas 404 00:27:21,680 --> 00:27:23,680 más utilizando tus métodos porque 405 00:27:23,680 --> 00:27:26,119 quien luego al final lee será siempre inputStream 406 00:27:26,119 --> 00:27:27,940 pero ya me creo los métodos 407 00:27:27,940 --> 00:27:30,160 que dice, leo los bytes suficientes 408 00:27:30,160 --> 00:27:32,099 lo interpreto como char y por lo tanto 409 00:27:32,099 --> 00:27:33,940 ahora trabajo con char, ese es un reader 410 00:27:33,940 --> 00:27:34,619 ¿vale? 411 00:27:35,180 --> 00:27:38,079 y en particular tenemos el fileInputStream 412 00:27:38,079 --> 00:27:39,940 y el fileReader que son 413 00:27:39,940 --> 00:27:42,200 digamos, métodos 414 00:27:42,200 --> 00:27:44,420 clases que permiten 415 00:27:44,420 --> 00:27:45,960 trabajar con ficheros 416 00:27:45,960 --> 00:27:47,559 ¿vale? entonces nosotros 417 00:27:47,559 --> 00:27:50,119 normalmente tendremos un fileInputStream 418 00:27:50,119 --> 00:27:51,900 que tiene dentro un 419 00:27:51,900 --> 00:27:53,180 inputStream como parámetro 420 00:27:53,180 --> 00:27:57,940 Vosotros que ya habéis entendido 421 00:27:57,940 --> 00:27:59,619 Cómo funciona la vida del programador 422 00:27:59,619 --> 00:28:01,619 Como yo os estoy nombrando 423 00:28:01,619 --> 00:28:03,079 Estas clases 424 00:28:03,079 --> 00:28:05,359 Hoy por la tarde cuando os aburrís 425 00:28:05,359 --> 00:28:07,180 Que no tenéis nada de mejor que hacer 426 00:28:07,180 --> 00:28:08,599 Os abrís el API 427 00:28:08,599 --> 00:28:11,740 Vais a mirar InputStream, InputStreamReader 428 00:28:11,740 --> 00:28:12,920 Y veis la diferencia 429 00:28:12,920 --> 00:28:15,099 Y veis que pueden hacer uno y otro 430 00:28:15,099 --> 00:28:16,960 Para que luego a partir de mañana 431 00:28:16,960 --> 00:28:19,220 Sepáis cuando usar uno 432 00:28:19,220 --> 00:28:20,059 Y cuando usar el otro 433 00:28:22,410 --> 00:28:28,309 Subiendo todavía a nivel más alto todavía, tenemos nuestro amigo el Buffered Reader. 434 00:28:28,549 --> 00:28:36,230 El Buffered Reader es un reader, es parecido al otro, que añade la posibilidad de crear un buffer. 435 00:28:36,490 --> 00:28:38,150 ¿Qué es un buffer? Es una memoria temporal. 436 00:28:38,609 --> 00:28:45,130 Es decir, que en vez de estar leyendo uno a uno los caracteres o los bytes o lo que sea, 437 00:28:45,549 --> 00:28:49,529 yo puedo crearme una memoria temporal y guardar allí los caracteres. 438 00:28:49,529 --> 00:28:58,289 Esto me permite crear métodos más útiles, más cómodos para nosotros los programadores 439 00:28:58,289 --> 00:29:02,690 Como por ejemplo, puedo leer una línea entera de golpe 440 00:29:02,690 --> 00:29:07,890 Mientras usando este de aquí, tengo que leer carácter por carácter 441 00:29:07,890 --> 00:29:12,430 Esperando al carácter que sea retorno de carro, el barra n 442 00:29:12,430 --> 00:29:14,430 Para decir, aquí se acaba la línea 443 00:29:14,430 --> 00:29:20,150 pues usando la clase BufferedReader le puedo decir usar la operación ReadLine 444 00:29:20,150 --> 00:29:24,710 que lee una línea entera y me la devuelve como un string, ¿vale? 445 00:29:24,970 --> 00:29:33,170 Entonces si yo estoy guardando en mi fichero los datos línea por línea 446 00:29:33,170 --> 00:29:38,029 pues utilizar un BufferedReader y leerlo línea por línea puede ser una opción, ¿vale? 447 00:29:38,029 --> 00:29:43,369 Una de las formas que nosotros usaremos esto es que cada objeto que nosotros guardaremos 448 00:29:43,369 --> 00:29:53,250 lo guardaremos en un formato textual, ¿vale? En una representación textual del objeto mismo y lo guardaremos un objeto por línea. 449 00:29:53,730 --> 00:30:01,869 De esta forma, cuando luego voy a leer el fichero, lo que voy a hacer es leer de golpe una línea y allí ya tengo todos los datos del primer objeto. 450 00:30:02,230 --> 00:30:11,269 Y ahora me lo voy parceando, me lo voy troceando, buscando cuál es el valor del primer atributo, el valor del segundo, para reconstruir el objeto. 451 00:30:11,269 --> 00:30:13,710 es una de las formas que se puede hacer 452 00:30:13,710 --> 00:30:15,470 y que veremos 453 00:30:15,470 --> 00:30:18,130 vamos a leer un archivo de texto 454 00:30:18,130 --> 00:30:19,950 ¿vale? entonces se utiliza 455 00:30:19,950 --> 00:30:21,910 una clase java.io 456 00:30:21,910 --> 00:30:23,970 file reader y la java.io 457 00:30:23,970 --> 00:30:25,650 buffered reader ¿vale? entonces 458 00:30:25,650 --> 00:30:27,990 file reader fr es igual a 459 00:30:27,990 --> 00:30:30,089 null, buffered reader br es igual a 460 00:30:30,089 --> 00:30:31,869 null, pues esto se podría hacer directamente 461 00:30:31,869 --> 00:30:33,269 aquí, pero me da igual 462 00:30:33,269 --> 00:30:36,049 fr es igual a new file reader 463 00:30:36,049 --> 00:30:37,549 de una ruta del archivo 464 00:30:37,549 --> 00:30:39,910 ¿vale? esta cosa de aquí crea 465 00:30:39,910 --> 00:30:46,950 un nuevo file reader, que es un lector, entonces estamos hablando de char especializado en 466 00:30:46,950 --> 00:30:55,910 ficheros, y aquí le pongo el nombre del fichero. Paréntesis sobre las rutas. Vosotros sabéis 467 00:30:55,910 --> 00:31:01,130 que en el mundo de la informática hay dos tipos de rutas, las rutas absolutas y las 468 00:31:01,130 --> 00:31:10,289 rutas relativas, ¿vale? ¿Dónde me espero que exista el fichero que voy a leer si no 469 00:31:10,289 --> 00:31:24,019 le pongo ninguna ruta? Si aquí pongo mi fichero.txt, ¿dónde aparecerá ese fichero? No. Sí o 470 00:31:24,019 --> 00:31:24,940 No, quién sabe. 471 00:31:26,579 --> 00:31:29,980 En el Eclipse es el proyecto. 472 00:31:31,990 --> 00:31:35,890 No source, no bin, el proyecto. 473 00:31:36,369 --> 00:31:38,970 Esa es considerada la working directory. 474 00:31:39,869 --> 00:31:44,430 Cuando yo busco un fichero sin decirle nada, lo busco allí. 475 00:31:44,750 --> 00:31:57,900 Si esto es un proyecto, el proyecto, no, es el disco duro que tiene que empezar a girar. 476 00:31:57,900 --> 00:32:01,380 Si yo tengo un proyecto, mi lista, qué sé yo 477 00:32:01,380 --> 00:32:04,440 Aquí es donde se acerca el fichero 478 00:32:04,440 --> 00:32:05,519 ¿Vale? 479 00:32:06,240 --> 00:32:07,319 No en source 480 00:32:07,319 --> 00:32:09,700 No en bin 481 00:32:09,700 --> 00:32:10,980 ¿Vale? 482 00:32:11,220 --> 00:32:13,839 Tened en cuenta que vosotros no lo pensáis 483 00:32:13,839 --> 00:32:16,039 Pero vosotros editáis esto 484 00:32:16,039 --> 00:32:18,339 Pero no ejecutáis esto 485 00:32:18,339 --> 00:32:20,240 Ejecutáis siempre esto 486 00:32:20,240 --> 00:32:23,880 Vosotros estáis ejecutando los .class 487 00:32:23,880 --> 00:32:24,759 ¿Vale? 488 00:32:24,759 --> 00:32:26,660 El eclipse en automático 489 00:32:26,660 --> 00:32:28,259 Cada vez que vosotros guardáis 490 00:32:28,259 --> 00:32:30,200 Pilla vuestro punto Java 491 00:32:30,200 --> 00:32:32,140 Le hace una compilación 492 00:32:32,140 --> 00:32:34,099 Y guarda los puntos class 493 00:32:34,099 --> 00:32:35,500 En esta carpeta de aquí 494 00:32:35,500 --> 00:32:37,440 Tiene la misma estructura 495 00:32:37,440 --> 00:32:39,119 Aquí está el paquete mi lista 496 00:32:39,119 --> 00:32:42,000 Aquí tendrá el paquete mi lista también 497 00:32:42,000 --> 00:32:45,599 Tiene la misma estructura del source 498 00:32:45,599 --> 00:32:46,980 Pero no se ejecuta el source 499 00:32:46,980 --> 00:32:47,960 Se ejecuta en el bin 500 00:32:47,960 --> 00:32:52,099 Si este fichero de aquí 501 00:32:52,099 --> 00:32:53,259 Le diera un 502 00:32:53,259 --> 00:32:56,079 Si este class de aquí 503 00:32:56,079 --> 00:32:58,099 leyera un fichero, me esperaría 504 00:32:58,099 --> 00:33:00,059 que el fichero tuviera que estar aquí 505 00:33:00,059 --> 00:33:02,039 ¿vale? y si yo lo 506 00:33:02,039 --> 00:33:03,619 lanzo con Java 507 00:33:03,619 --> 00:33:06,299 directamente a esta clase 508 00:33:06,299 --> 00:33:08,200 desde esta carpeta, posiblemente 509 00:33:08,200 --> 00:33:09,720 debería estar aquí, ¿vale? 510 00:33:09,980 --> 00:33:11,500 pero a nivel de Eclipse 511 00:33:11,500 --> 00:33:14,019 Eclipse lo va a buscar aquí, esta es su 512 00:33:14,019 --> 00:33:15,440 working directory, digamos que 513 00:33:15,440 --> 00:33:17,859 el punto donde arranca 514 00:33:17,859 --> 00:33:19,880 él piensa de estar en esta 515 00:33:19,880 --> 00:33:22,200 directory de aquí, yo puedo crearme 516 00:33:22,200 --> 00:33:24,079 aquí una carpeta que se llame ficheros 517 00:33:24,079 --> 00:33:25,960 y poner ahí dentro los ficheros 518 00:33:25,960 --> 00:33:26,940 O cosas por el estilo 519 00:33:26,940 --> 00:33:29,660 Es un error enorme 520 00:33:29,660 --> 00:33:30,940 Colosal 521 00:33:30,940 --> 00:33:32,980 Y os suspendo instantáneamente 522 00:33:32,980 --> 00:33:35,619 Si me ponéis algo así 523 00:33:35,619 --> 00:33:42,380 No puedo hacerlo más grande 524 00:33:42,380 --> 00:33:44,019 Porque luego se me bloquea la cosa 525 00:33:44,019 --> 00:33:46,220 Como de dos puntos, barra, prog 526 00:33:46,220 --> 00:33:48,000 24, 25, barra, mi lista 527 00:33:48,000 --> 00:33:49,200 Es decir, una ruta 528 00:33:49,200 --> 00:33:50,880 Absoluta 529 00:33:50,880 --> 00:33:53,440 Las rutas absolutas no se usan 530 00:33:53,440 --> 00:33:53,819 ¿Por qué? 531 00:33:58,269 --> 00:33:59,509 ¿Sí? ¿Se entiende? 532 00:34:00,369 --> 00:34:02,789 Es lo mismo que os pasa en HTML 533 00:34:02,789 --> 00:34:05,569 cuando vosotros tenéis HTML o el CSS 534 00:34:05,569 --> 00:34:08,630 si le ponéis la ruta relativa 535 00:34:08,630 --> 00:34:11,050 y luego copiáis la carpeta en otro ordenador 536 00:34:11,050 --> 00:34:12,230 os funciona perfectamente 537 00:34:12,230 --> 00:34:14,750 si le habéis puesto la ruta absoluta 538 00:34:14,750 --> 00:34:16,130 y lo lleváis a otro ordenador 539 00:34:16,130 --> 00:34:18,010 que no tiene exactamente vuestra ruta 540 00:34:18,010 --> 00:34:19,230 pues no va a funcionar 541 00:34:19,230 --> 00:34:21,050 y esto os pasa muchas veces 542 00:34:21,050 --> 00:34:23,469 porque vosotros trabajáis siempre solo en el mismo ordenador 543 00:34:23,469 --> 00:34:25,250 luego lo subís al servidor 544 00:34:25,250 --> 00:34:27,250 que este paso no lo estáis haciendo todavía 545 00:34:27,250 --> 00:34:29,010 pero lo subís al servidor y no funciona nada 546 00:34:29,010 --> 00:34:31,070 porque habéis puesto esta cosa aquí 547 00:34:31,070 --> 00:34:32,510 es suspenso automático 548 00:34:32,510 --> 00:34:40,639 Entonces, con esta de aquí me he creado un file reader 549 00:34:40,639 --> 00:34:42,519 Dejad de hablar vosotros dos 550 00:34:42,519 --> 00:34:45,480 Es 20 minutos, quiero reís de no sé qué 551 00:34:45,480 --> 00:34:50,360 Sí, vosotros dos 552 00:34:50,360 --> 00:34:53,840 Vale, entonces, con esto he creado el file reader 553 00:34:53,840 --> 00:34:56,480 El file reader es esta cosa que me permitiría leer 554 00:34:56,480 --> 00:34:59,000 ¿Vale? Leer carácter por carácter es de un fichero 555 00:34:59,000 --> 00:35:00,179 Es una clase de ese estilo 556 00:35:00,179 --> 00:35:04,800 Pero yo quiero leerme una fila entera, una línea entera 557 00:35:04,800 --> 00:35:21,139 Entonces, creo un BufferedReader, que es NewBufferedReader, y le paso como parámetro este FileReader. Aquí se podría pasar un file. A este punto, puedo hacer una cosa de este estilo. 558 00:35:21,139 --> 00:35:22,360 mientras 559 00:35:22,360 --> 00:35:24,559 br.redline 560 00:35:24,559 --> 00:35:26,679 esta cosa de aquí es un 561 00:35:26,679 --> 00:35:28,460 es leer una 562 00:35:28,460 --> 00:35:30,320 fila, una línea 563 00:35:30,320 --> 00:35:31,719 de texto, ¿vale? 564 00:35:32,019 --> 00:35:34,500 esto me lo guardas dentro de línea 565 00:35:34,500 --> 00:35:36,320 y mientras que esta línea 566 00:35:36,320 --> 00:35:37,360 no sea null 567 00:35:37,360 --> 00:35:39,800 es decir, que he leído algo 568 00:35:39,800 --> 00:35:42,280 me he ido al fichero, he leído 569 00:35:42,280 --> 00:35:44,760 y la respuesta que me ha dado no ha sido null 570 00:35:44,760 --> 00:35:46,019 ¿vale? pues 571 00:35:46,019 --> 00:35:48,199 imprimo esa cosa 572 00:35:48,199 --> 00:35:49,199 en pantalla 573 00:35:49,199 --> 00:35:55,179 aquí habrá errores, cosas por el estilo, etc 574 00:35:55,179 --> 00:35:58,980 finalmente cuando he acabado de leer todas las cosas 575 00:35:58,980 --> 00:36:02,820 y cuando llegará un momento en que esto explote o acabe con un null 576 00:36:02,820 --> 00:36:07,800 pues entonces lo que hago aquí es cerrar el file reader 577 00:36:07,800 --> 00:36:14,980 esto en el 95% de nuestros ejercicios no sirverá 578 00:36:14,980 --> 00:36:18,460 porque nosotros leemos y acabamos el programa 579 00:36:18,460 --> 00:36:35,500 Son micro ejercicios. En términos de un proyecto más grande, yo debería estar pendiente de cuando un fichero se ha leído y no me hace falta más y que entonces lo pueda cerrar, pueda cerrar el canal de comunicación con ese fichero. 580 00:36:35,500 --> 00:36:37,199 porque si se me olvida 581 00:36:37,199 --> 00:36:39,679 y yo tengo que abrir un millón de ficheros 582 00:36:39,679 --> 00:36:41,659 y estos millones de ficheros me ocupan 583 00:36:41,659 --> 00:36:43,440 cada uno un trocito de espacio 584 00:36:43,440 --> 00:36:45,619 en mi RAM, pues llega un momento 585 00:36:45,619 --> 00:36:47,500 que tengo memory slicks en el sentido 586 00:36:47,500 --> 00:36:49,739 de objetos que no me sirven 587 00:36:49,739 --> 00:36:51,280 de nada, que se podrían quitar 588 00:36:51,280 --> 00:36:53,360 pero no he quitado recursos 589 00:36:53,360 --> 00:36:55,300 que se quedan allí ocupando espacio 590 00:36:55,300 --> 00:36:57,420 porque en cada ejecución yo 591 00:36:57,420 --> 00:36:59,619 creo un file reader y no lo 592 00:36:59,619 --> 00:37:01,699 cierro y por lo tanto 593 00:37:01,699 --> 00:37:03,539 él asume que antes o después 594 00:37:03,539 --> 00:37:05,380 lo vas a reutilizar, entonces 595 00:37:05,380 --> 00:37:09,340 se me queda ahí abierto, vale, entonces acostumbraos 596 00:37:09,340 --> 00:37:13,340 a hacerlo, vale, si no, no, existe también 597 00:37:13,340 --> 00:37:17,440 una versión del try catch que es el try con recursos en el que aquí 598 00:37:17,440 --> 00:37:21,420 entre paréntesis declaráis unos 599 00:37:21,420 --> 00:37:24,820 recursos que vais a utilizar aquí dentro, como por ejemplo estos dos 600 00:37:24,820 --> 00:37:29,179 vale, y él en automático cuando acaba el block que trae 601 00:37:29,179 --> 00:37:33,360 los destruye y hace un close de esa cosa aquí, vale 602 00:37:33,360 --> 00:37:35,139 hoy en día se suele utilizar 603 00:37:35,139 --> 00:37:37,400 no me interesa particularmente 604 00:37:37,400 --> 00:37:38,960 pero lo veréis en códigos 605 00:37:38,960 --> 00:37:41,460 y cuando luego programaréis 606 00:37:41,460 --> 00:37:43,659 ahí afuera, posiblemente lo tendréis que utilizar 607 00:37:43,659 --> 00:37:48,500 escritura de un archivo de texto 608 00:37:48,500 --> 00:37:51,679 en vez de file reader uso file writer 609 00:37:51,679 --> 00:37:53,760 en vez de baffered reader 610 00:37:53,760 --> 00:37:55,340 uso print writer 611 00:37:55,340 --> 00:37:57,219 print writer 612 00:37:57,219 --> 00:37:59,980 a lo mejor os podría sonar 613 00:37:59,980 --> 00:38:00,679 de algo 614 00:38:00,679 --> 00:38:07,320 vuestro System.out 615 00:38:07,320 --> 00:38:09,500 es un objeto PrintWriter 616 00:38:09,500 --> 00:38:11,849 ¿sí? 617 00:38:12,170 --> 00:38:14,630 entonces los métodos que se encuentran 618 00:38:14,630 --> 00:38:16,829 aquí, como por ejemplo PrintLn 619 00:38:16,829 --> 00:38:18,610 son los que se utilizan 620 00:38:18,610 --> 00:38:20,269 nosotros desde el primer día 621 00:38:20,269 --> 00:38:22,650 literalmente que hemos programado 622 00:38:22,650 --> 00:38:24,309 cuando hemos hecho System.out 623 00:38:24,309 --> 00:38:26,909 PrintLn, System.out lo que es 624 00:38:26,909 --> 00:38:28,590 es un objeto de tipo 625 00:38:28,590 --> 00:38:30,550 PrintWriter, PrintLn 626 00:38:30,550 --> 00:38:32,429 es un método de PrintWriter que me escribe 627 00:38:32,429 --> 00:38:34,710 la string que yo 628 00:38:34,710 --> 00:38:41,150 quiero y al final le pone un retorno de carro vale entonces el file writer 629 00:38:41,150 --> 00:38:47,030 igualmente new file writer con la ruta del archivo para crear la cosa aquí un 630 00:38:47,030 --> 00:38:51,210 poquito ahora os explico que quiere decir esto vale luego el print writer es un 631 00:38:51,210 --> 00:38:56,670 nuevo print writer que sostanzialmente pilla este file writer como base el file 632 00:38:56,670 --> 00:39:00,590 writer será el que escribe realmente el print writer es el que añade algunas 633 00:39:00,590 --> 00:39:03,869 funcionalidades como escribir una línea eso quiere decir que escribo lo que 634 00:39:03,869 --> 00:39:14,710 Entonces, por ejemplo, aquí lo que hace es que por 10 líneas lo que hace es escribir línea 1, línea 2, línea 3, línea 4 en un fichero, ¿vale? 635 00:39:14,710 --> 00:39:19,929 Si explota algo, pilla la excepción, finalmente acaba, ¿vale? 636 00:39:20,329 --> 00:39:33,289 Ten en cuenta que cuando creáis esto, el FileWriter está pensado para que tú abras un fichero y lo borres enteros y lo escribas desde el principio, ¿sí? 637 00:39:33,869 --> 00:39:53,019 Si tú ya tienes un fichero y quieres añadir, pegar detrás cosas a ese fichero, tienes que ponerle true, lo que sea, coma true, ¿vale? Este es un parámetro que te dice, que normalmente es a false, ¿vale? 638 00:39:53,019 --> 00:39:55,139 Que te dice si tú lo que quieres hacer 639 00:39:55,139 --> 00:39:56,340 Cuando escribes es 640 00:39:56,340 --> 00:39:59,380 Escribir desde el principio un nuevo fichero 641 00:39:59,380 --> 00:40:01,739 Hasta si este ya existe 642 00:40:01,739 --> 00:40:03,300 Borrar lo que estaba dentro 643 00:40:03,300 --> 00:40:04,980 Y quedarte con lo nuevo 644 00:40:04,980 --> 00:40:07,360 O si quieres hacer la operación de append 645 00:40:07,360 --> 00:40:08,619 O sea 646 00:40:08,619 --> 00:40:10,699 Lo que estaba, estaba 647 00:40:10,699 --> 00:40:12,400 Y append detrás 648 00:40:12,400 --> 00:40:13,960 Las cosas nuevas 649 00:40:13,960 --> 00:40:15,820 ¿Dudas? 650 00:40:18,889 --> 00:40:20,530 Entonces, escritura de un archivo binario 651 00:40:20,530 --> 00:40:21,590 Vale 652 00:40:21,590 --> 00:40:29,269 aquí usa BufferedReader igualmente pero luego no lo debería utilizar BossWrite 653 00:40:29,269 --> 00:40:30,050 lo escribe 654 00:40:30,050 --> 00:40:37,170 este es un FileInputStream, BufferedInputStream 655 00:40:37,170 --> 00:40:41,369 FileOutputStream y BufferedOutputStream 656 00:40:41,369 --> 00:40:44,250 lo que hace es utilizar Arrays 657 00:40:44,250 --> 00:40:47,010 entonces crea un Array de 1000 posiciones 658 00:40:47,010 --> 00:40:50,170 hace bis.read de Array 659 00:40:50,170 --> 00:40:52,789 este de aquí, vis.read 660 00:40:52,789 --> 00:40:54,769 lo que hace es, te paso 661 00:40:54,769 --> 00:40:56,530 un array, y yo 662 00:40:56,530 --> 00:40:58,889 intento leer desde el fichero 663 00:40:58,889 --> 00:41:00,469 hasta que el array 664 00:41:00,469 --> 00:41:02,650 esté lleno, si hay 665 00:41:02,650 --> 00:41:04,690 al menos 1000 bytes, leeré 666 00:41:04,690 --> 00:41:06,750 1000 bytes de golpe, y ahora 667 00:41:06,750 --> 00:41:08,550 tú tienes 1000 bytes, ¿por qué 1000? 668 00:41:08,610 --> 00:41:10,329 porque aquí he puesto 1000, si pusiera 100 669 00:41:10,329 --> 00:41:11,730 pusiera 100, ¿sí? 670 00:41:12,570 --> 00:41:14,530 si leo menos, porque 671 00:41:14,530 --> 00:41:16,690 en el fichero no hay 1000 bytes, hay solo 7 672 00:41:16,690 --> 00:41:19,150 bytes, pues yo te devuelvo 673 00:41:19,150 --> 00:41:23,590 cuántos bytes he leído, si alcanzo el final del fichero 674 00:41:23,590 --> 00:41:26,809 antes de haber rellenado estos 1000 bytes 675 00:41:26,809 --> 00:41:31,110 te rellenaré solo los bytes que podía, los primeros 7 bytes 676 00:41:31,110 --> 00:41:34,730 por ejemplo, pero aquí te devuelvo cuántos he leído 677 00:41:34,730 --> 00:41:38,730 con esto, yo puedo decir que mientras leída es mayor que 0 678 00:41:38,730 --> 00:41:43,210 lo que hago es, esto quiere decir que he leído algo, porque si hubiese 679 00:41:43,210 --> 00:41:46,210 0, quiere decir que no he leído nada, vale 680 00:41:46,210 --> 00:41:49,030 Y lo que hace él es 681 00:41:49,030 --> 00:41:50,510 Boss.write 682 00:41:50,510 --> 00:41:53,369 Array, o sea, escribe este array 683 00:41:53,369 --> 00:41:56,210 A partir desde la posición 0 684 00:41:56,210 --> 00:41:58,170 Hasta la posición leído 685 00:41:58,170 --> 00:41:59,829 Entonces si he leído 1000 686 00:41:59,829 --> 00:42:01,650 Sería desde 0 hasta 1000 687 00:42:01,650 --> 00:42:03,889 Si he leído 7, desde 0 hasta 7 688 00:42:03,889 --> 00:42:05,670 ¿Sí? 689 00:42:07,309 --> 00:42:08,929 Y leídos es igual a 690 00:42:08,929 --> 00:42:10,570 Biz.readArray 691 00:42:10,570 --> 00:42:12,449 Esto lo leo otra vez 692 00:42:12,449 --> 00:42:13,369 No sé por qué 693 00:42:13,369 --> 00:42:15,550 Ah, sí, porque se prepara para la siguiente 694 00:42:15,550 --> 00:42:17,969 vuelta de cosas. Hasta que no lea 695 00:42:17,969 --> 00:42:19,889 nada. A ese punto, cierra 696 00:42:19,889 --> 00:42:21,349 los dos. ¿Qué hace esta cosa aquí? 697 00:42:27,469 --> 00:42:32,119 Y, no. 698 00:42:32,719 --> 00:42:34,519 No hay ningún... Existe un punto, punto, punto, 699 00:42:34,599 --> 00:42:36,679 escribirlo en otro fichero. Este es 700 00:42:36,679 --> 00:42:38,559 copiar un fichero. Lo dice aquí. 701 00:42:38,840 --> 00:42:39,699 Copia de un fichero. 702 00:42:41,739 --> 00:42:42,659 Si os fijáis, 703 00:42:42,820 --> 00:42:44,619 tiene un origen, 704 00:42:45,380 --> 00:42:46,460 tiene una copia, 705 00:42:47,119 --> 00:42:48,519 ¿vale? Y lo que hace es 706 00:42:48,519 --> 00:42:50,880 leer de mil en mil 707 00:42:50,880 --> 00:42:52,739 los bytes de un fichero 708 00:42:52,739 --> 00:42:54,760 y escribirlos en otro fichero. 709 00:42:55,119 --> 00:42:56,380 Leo mil, escribo mil. 710 00:42:56,500 --> 00:42:57,599 Leo mil, escribo mil. 711 00:42:57,739 --> 00:42:59,480 Leo siete, escribo siete, acabado. 712 00:43:01,489 --> 00:43:02,690 Hasta que no lea nada, 713 00:43:03,710 --> 00:43:05,510 leo cero, y entonces ya está. 714 00:43:08,139 --> 00:43:11,300 Esto es una copia a bajo nivel. 715 00:43:12,000 --> 00:43:14,079 Estamos trabajando con arrays. 716 00:43:14,199 --> 00:43:15,400 ¿Qué es esto? ¿Un fichero de texto? 717 00:43:15,900 --> 00:43:17,119 Me vale, me funciona. 718 00:43:17,119 --> 00:43:19,940 ¿Es un exe? Me vale, me funciona. 719 00:43:20,619 --> 00:43:23,139 ¿Es un dat? Me vale, me funciona. 720 00:43:23,300 --> 00:43:24,980 ¿Es un word? Me vale, me funciona. 721 00:43:30,579 --> 00:43:46,800 qué estructura dinámica no sé qué me estás diciendo en fichero donde donde quieres usar 722 00:43:46,800 --> 00:43:58,920 no esto es a byte porque la read no te pilla una rey list te pilla una rey en la en la bright no 723 00:43:58,920 --> 00:44:06,059 te pilla una rey list te pilla una rey entonces esta es la versión básica de la cosa y no hay 724 00:44:06,059 --> 00:44:12,000 hay una versión de la braille que te pille es ahí la puedes hacer si tú puedes crearte tu propio 725 00:44:12,000 --> 00:44:19,199 my input stream my output stream que lo que hace es pillar de un array list pero debajo lo que hará 726 00:44:19,199 --> 00:44:24,820 es crearte una reunión file input stream y utilizar a los arrays pero luego una vez que tú lo has 727 00:44:24,820 --> 00:44:33,719 implementado tú desde fuera la utilizarás con lo que quieras si dudas y hasta aquí hemos llegado