Saltar navegación

Clase 24-05-24 - 3 - Contenido educativo

Ajuste de pantalla

El ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:

Subido el 25 de mayo de 2024 por Raquel G.

15 visualizaciones

Descargar la transcripción

A ver, nosotros en este ejemplo que acabamos de hacer aquí, cuando hemos mandado los archivos con el object output string aquí abajo, en guardar, 00:00:01
lo hemos asociado a un file output string al que no le hemos dado la opción de añadir. 00:00:13
Esto no se lo hemos dicho. 00:00:17
Con lo cual, el fichero lo creaba siempre limpio. 00:00:19
Y no pasaba nada, porque como volcábamos antes todos a la lista, en la lista añadíamos lo demás y luego la lista entera se iba al fichero pisándolo de antes. 00:00:22
Pero no había nada, porque es que en la lista ya habíamos volcado previamente a lo anterior. 00:00:33
Entonces el funcionamiento estaba bien. 00:00:36
Pero bueno, puede haber una situación en la que nosotros no hemos recuperado el archivo previamente, 00:00:38
sino nuestra aplicación crea objetos nuevos y esos objetos nuevos que los mande al archivo a continuación de los que hubiera. 00:00:43
Y ya está, a continuación de los que hubiera. 00:00:51
No ha recuperado previamente los otros porque esos ya están ahí y no quiere trabajar con ellos. 00:00:53
En ese caso, habríamos añadido el true ahí, ¿no? 00:00:57
Pues vamos a hacerlo en este otro proyecto 00:01:00
Vale, vamos a hacer un método 00:01:04
Para guardar un objeto en el archivo 00:01:10
Simplemente 00:01:13
Vamos a hacer un método para 00:01:14
Guardar un alumno en el archivo 00:01:21
Y ahora le vamos a pasar aquí el nombre del archivo 00:01:23
Fichero alumnos 00:01:27
Bueno, pues que tendríamos que hacer aquí 00:01:33
Pues como vamos a guardar un objeto 00:01:40
Pues otra vez, el object output string, new file output string, y aquí el fichero alumnos. 00:01:41
¡Hala! Ya está. 00:02:18
Venga, importamos. 00:02:19
No importa si importamos. 00:02:21
Import. 00:02:28
Y propagamos excepción. 00:02:30
bueno, queremos escribir 00:02:32
un único, ah bueno y perdón 00:02:40
queremos este objeto 00:02:42
añadirlo a los que hubiera de antes 00:02:44
a los que hubiera de antes 00:02:46
luego al file output 00:02:48
stream al que nos enganchamos 00:02:51
le tenemos que añadir un true 00:02:52
añadimos un true a este file output stream 00:02:53
para que añada a los objetos 00:02:57
que hubiera de antes 00:02:58
y ahora ya escribimos el objeto 00:02:59
este es solo uno 00:03:02
pues venga 00:03:04
escribimos nuestro objeto 00:03:05
bueno, guardar alumno es que no le hemos pasado 00:03:10
a guardar, vaya tontería 00:03:12
no le hemos pasado 00:03:15
ala, este 00:03:16
y ahora hemos terminado 00:03:18
bueno, pues ahora vamos a hacer una aplicación 00:03:23
que lo que hace es 00:03:34
solicitar objetos alumno 00:03:36
y mandarlos al fichero 00:03:38
ya está, entonces que la aplicación 00:03:39
arranca una segunda vez 00:03:42
los nuevos que le pidamos 00:03:44
irán al fichero y se acabó 00:03:46
Y ya está, pues bien, vamos a hacer una aplicación 00:03:48
Simplemente 00:03:50
Que esté todo el rato 00:03:51
Bueno, todo el rato 00:03:54
Mientras no le digamos 00:03:56
Que introduzca 00:03:58
Vamos a decirle 00:04:00
Venga, mete NIF 00:04:06
Pues que meta el NIF 00:04:07
Ver cadena 00:04:11
Este será 00:04:18
Vamos a hacer aquí 00:04:21
El alumno A 00:04:24
Y este alumno A 00:04:24
Le hacemos que su NIF 00:04:32
.setNif 00:04:34
Que su Nif sea el resultado de leer del teclado 00:04:41
Esto así no 00:04:46
Ah, esta ya tiene Nif 00:04:51
Y vamos a pedirle el nombre, que es la única otra propiedad que tenía 00:04:56
Nombre 00:04:59
Vale, y ahora 00:05:03
Guardamos el objeto alumno en el fichero 00:05:12
Guardar alumno era esto 00:05:16
Guardar alumno 00:05:20
al que le damos el alumno que acabamos de crear 00:05:23
y el fichero de alumnos 00:05:26
este 00:05:28
y este bucle va a estar así todo el rato 00:05:30
mientras él no nos diga a continuar 00:05:33
sí o no y ya está 00:05:35
aquí vamos a hacer 00:05:37
la respuesta 00:06:05
así 00:06:06
y ahora mientras 00:06:12
la opción sea 00:06:17
distinta 00:06:22
de continuar 00:06:23
de no 00:06:29
Mientras sea distinta de no 00:06:30
Continúas 00:06:32
Y nos falta declararla aquí 00:06:33
Igual a esto 00:06:35
Vale, pues nada 00:06:43
No hace falta ni inicializarla 00:06:46
Porque la le stream 00:06:49
Vale, pues nada 00:06:51
Y esto es la excepción 00:06:54
Vale, pues nada 00:06:57
Pide alumno, lo guarda 00:07:02
¿Quieres continuar? 00:07:04
Mientras él no diga que no 00:07:06
Otra vez, pide alumno, guarda, etc 00:07:08
Y todo el rato 00:07:10
Que he hecho mal 00:07:11
Ah, perdón, perdón 00:07:12
Sí, sí, sí 00:07:16
Sí, vale 00:07:18
Vale, pues nada 00:07:21
Vamos a meter con esta aplicación 00:07:24
Un alumno 00:07:27
Nif1234 00:07:27
Nombre Pepito 00:07:40
Ah, que alumno 00:07:43
No es serializable 00:07:45
¿Veis? Como decía que esto es lo típico 00:07:46
Que siempre se olvida 00:07:49
Implements 00:07:50
Por eso 00:07:54
Es bueno haber visto la opción una primera vez 00:07:55
El error 00:07:58
Vale, pues venga 00:07:59
Lo ejecutamos otra vez 00:08:04
3, 4 00:08:06
1, 2, 3, 4 00:08:09
No, solo uno 00:08:12
Pues hala, ya está 00:08:18
Ya tenemos ahí 00:08:20
Nuestro fichero de alumnos 00:08:22
Que madre de Dios 00:08:30
No, este no puede ser 00:08:32
Es demasiado largo 00:08:37
¿Dónde me he metido yo? 00:08:39
No, sí 00:08:42
Ah, esta es porque tiene 00:08:43
Uf, qué fichero tan horriblemente largo 00:08:53
No, es que esto no me cuadra 00:08:58
Este contenido 00:09:05
No me cuadra nada este contenido 00:09:06
A ver 00:09:11
Alumno A 00:09:12
Y aquí qué he hecho 00:09:17
Guardar alumno A 00:09:25
Año alumno 00:09:28
A, sednif 00:09:29
Bueno, no sé 00:09:31
Ese contenido se me resulta un poco raro, pero bueno 00:09:36
claro, es que me tendría que aparecer 00:09:38
sobre una línea, por eso digo 00:09:42
que qué he hecho yo aquí raro 00:09:44
vale, ahora 00:09:45
nuestros datos, los de esta aplicación 00:09:48
aquí ya no hay lista que tenga datos 00:09:51
ni nada, están todos en archivo 00:09:53
imaginaos que ahora queremos hacer un método que me diga 00:09:54
oye, dime el nombre del alumno con este 00:09:57
nif, por ejemplo, pues ese 00:09:59
método tendrá que trabajar con el archivo 00:10:01
porque aquí no hay una lista que tenga los datos 00:10:03
ni nada, pues vamos a hacer ese método 00:10:05
vamos a hacer el método de 00:10:07
recuperar nombre de alumno 00:10:11
dado un if 00:10:13
y dado 00:10:21
el nombre del archivo donde están los datos 00:10:24
venga, pues aquí tenemos 00:10:26
una funcionalidad que dado 00:10:35
un if public 00:10:37
recupera nombre, le vamos a poner aquí 00:10:38
un return null para que se calle 00:10:41
vale 00:10:42
pues aquí tenemos una funcionalidad 00:10:44
dado un if, devuélveme el 00:10:46
nombre de ese alumno 00:10:49
aquí ahora ya la diferencia 00:10:51
respecto al resto de aplicaciones pasadas 00:10:54
es que nosotros antes teníamos 00:10:56
todos los alumnos 00:10:58
los teníamos en una lista 00:11:00
o en un set o en un map, ahí estaban todos 00:11:02
y entonces aquí tranquilamente 00:11:04
nos íbamos a esa lista, ese set y ese map 00:11:06
y lo buscábamos 00:11:08
aquí no hay ninguna lista, no hay ningún set 00:11:09
no hay ningún map, no hay nada 00:11:12
los alumnos están en el fichero 00:11:13
pues tendremos que abrir el fichero 00:11:16
empezar a leer de él, a tirar de los objetos 00:11:18
hasta que encontremos un objeto cuyo NIF sea ese. 00:11:20
Porque ahí es donde están. 00:11:23
Están solo ahí. 00:11:24
En toda esta aplicación, por más que miremos, 00:11:26
no hay ninguna lista con alumnos. 00:11:28
Están todos aquí. 00:11:30
En este archivo que me han dado. 00:11:32
Vale, pues venga, vamos a empezar a leer del archivo. 00:11:34
Vamos a recuperar alumno por alumno. 00:11:37
Cuando encontremos aquel cuyo NIF es esto, 00:11:39
accedemos al nombre y lo mostramos. 00:11:41
Eso es lo que haríamos, ¿no? 00:11:43
En lugar de recorrer la lista, 00:11:45
vamos a leer el archivo. 00:11:47
Vale, pues vamos a hacer el bucle de lectura otra vez 00:11:48
Voy a copiar y pegar el anterior 00:11:52
Que lo tendré aquí abajo 00:11:58
Bueno, de hecho lo voy a copiar todo para que si el fichero no existe lo diga 00:12:10
Vale, ahora lo... 00:12:24
Aquí estamos 00:12:30
Vamos a copiar y ahora lo vemos 00:12:34
Vale, pues lo primero que hacemos 00:12:36
fichero alumnos se llama 00:12:37
vamos a ver si existe 00:12:40
porque si no existe 00:12:44
el nombre 00:12:45
no hay nombre, no existe el archivo 00:12:46
es que no puedo recuperar el nombre de ningún 00:12:50
alumno, ya está 00:12:52
vale, ahora el archivo existe 00:12:53
pues ahora ya vamos a abrirlo para leer 00:12:55
como tiene objetos 00:12:57
serializados 00:13:00
pues con object input string 00:13:01
fichero alumnos, nada, no doy un 00:13:03
fichero alumnos 00:13:08
hala, ya está, ya está abierto 00:13:12
y ahora, bucle de lectura, vamos a empezar a leer 00:13:15
esto lo quito, el bucle de lectura 00:13:17
es el mismo, intento 00:13:22
hacer mi lectura de mi objeto 00:13:24
readObject 00:13:26
que sé que es un objeto de tipo alumno 00:13:29
le hago el casting y esto me dirá 00:13:32
que excepción que haces, postRows 00:13:33
vale 00:13:35
y ahora, ¿qué hacemos con 00:13:37
este alumno que hemos leído? 00:13:40
pues venga, vamos a ver si 00:13:41
el need de este alumno que acabo de leer 00:13:44
es el que me han dicho 00:13:46
porque si lo es, pues ya tengo el nombre 00:13:47
bla bla bla 00:13:49
entonces el resultado, vamos a guardarlo aquí 00:13:50
el resultado 00:13:53
el nombre resultado 00:13:54
lo vamos a poner aquí 00:13:56
inicialmente es esto 00:13:58
y ahora 00:14:01
si a.getNif 00:14:02
resulta 00:14:05
que es igual 00:14:07
al nombre 00:14:08
perdón, al Nif 00:14:10
que me han pasado como parámetro 00:14:12
pues ya tengo el resultado 00:14:15
el resultado es 00:14:17
el nombre de este alumno 00:14:19
y no se llama result sino nombre 00:14:21
y ahora cuando 00:14:26
esto ya ha terminado 00:14:32
devuelvo 00:14:33
vale, pues mi método es este, primero 00:14:35
si no existe no tengo nada que hacer 00:14:44
devuelvo un null como nombre 00:14:47
si existe, lo abro para 00:14:48
leer objetos 00:14:50
me hago el bucle de lectura, me voy leyendo 00:14:51
alumno por alumno 00:14:54
y con cada uno de ellos 00:14:55
su nombre es igual, su if es igual 00:14:59
que me han pasado 00:15:01
sí, pues ya lo tengo 00:15:02
y ya está, y return nombre 00:15:04
aquí incluso 00:15:06
podría ya de paso en este if 00:15:08
meter un fin archivo 00:15:11
para que el while ya termine 00:15:13
y no siga leyendo 00:15:15
podría, y así ya, porque si tiene mil alumnos 00:15:16
y lo he encontrado en el primero 00:15:21
pues hombre 00:15:22
podría ya hacer esto 00:15:24
y así no se está ese leyendo 00:15:27
hasta fin de archivo cuando ya lo ha encontrado 00:15:33
entonces este bucle ahora saldría 00:15:35
por dos motivos, o bien 00:15:37
porque ha encontrado ya al alumno con ese nif 00:15:39
o bien porque ha llegado 00:15:41
al final y no lo ha encontrado 00:15:43
por una de las dos razones 00:15:44
podría salir, porque ha llegado al final 00:15:47
y no lo ha encontrado 00:15:49
o porque lo ha encontrado 00:15:50
y ya me lo ha devuelto 00:15:52
vale, retú un nombre y ya está 00:15:54
y aquí tengo 00:15:57
un rojo en este porque este 00:16:01
no hace parte de importar 00:16:03
que este está en el propio paquete 00:16:05
ahí, vale 00:16:07
vale, pues venga, entonces 00:16:09
este recuperaría directamente 00:16:14
del archivo, es que no los tengo en una lista 00:16:17
los tengo en el archivo 00:16:18
pues ahora, nuestro main 00:16:19
ha metido un alumno 00:16:22
hemos metido solo uno 00:16:24
que en mi caso tenía un 234 00:16:29
voy a comentarlo para que no meta 00:16:32
más, porque no quiero que meta más por una razón. Y ahora vamos a leer el alumno. Vamos 00:16:35
a buscar un alumno. Introduce NIF de búsqueda. Introduce NIF de búsqueda. Vamos a leer el 00:16:45
NIF de búsqueda. Y ahora llamamos al método para que nos devuelva el nombre que el método 00:16:57
se llamaba recupera nombre 00:17:14
recupera nombre 00:17:16
para este nif sobre el archivo alumnos 00:17:22
que es sobre el que estamos trabajando 00:17:24
y ahora si nombre es 00:17:25
diferente, si nombre es null 00:17:27
pues es que no existe 00:17:29
¿verdad? 00:17:31
el alumno no existe 00:17:39
y si no 00:17:41
pues devolvemos el nombre y ya está 00:17:43
vale, y esto me da 00:17:46
una excepción y listo 00:17:50
vale, pues entonces yo había ejecutado esto antes una sola 00:17:55
vez, con lo cual 00:17:58
El fichero de alumnos 00:17:59
Solo tiene un alumno 00:18:01
Que aquí, aunque yo no entienda nada 00:18:02
Como que no matricula 00:18:04
Este no es 00:18:08
Estoy volviendo loca, claro 00:18:09
Es que es este 00:18:11
Yo tengo este, que aunque no entienda nada 00:18:12
Aquí puedo ver que me ha metido solo uno 00:18:17
Porque veo aquí un NIF 00:18:19
Patatín 00:18:20
Y veo aquí un nombre 00:18:23
Que es Pepito, veo el NIF 00:18:25
1, 2, 3, 4, o sea, solo tengo uno 00:18:26
Vale 00:18:28
Pues venga, vamos a hacer nuestro main 00:18:30
A ver si encuentra el de 1, 2, 3, 4 00:18:33
1, 2, 3, 4 00:18:35
Bien, perfecto 00:18:42
Y no estamos trabajando ni con 00:18:44
Datos en la aplicación, en listas 00:18:46
Ni en nada, los datos están en el archivo 00:18:48
Están en el archivo 00:18:50
No tengo aquí una colección 00:18:51
Y tiene sentido trabajar así 00:18:53
Porque si, imaginaos que esta aplicación 00:18:55
Trabaja con 2000 alumnos 00:18:58
Si tiene que tener los 2000 00:19:00
En la lista todo el rato 00:19:02
pedazo de ocupación 00:19:04
que se hace de la RAM 00:19:06
hombre, está en el archivo, él los tiene 00:19:07
que quiere hacer una consulta, lee del archivo 00:19:10
como hemos visto, va leyendo hasta que lo encuentra 00:19:11
que quiere insertar uno nuevo 00:19:14
lo añade al final 00:19:15
y así yo tengo mis datos en el archivo 00:19:17
que son 50.000 00:19:20
son 50.000, están en el archivo 00:19:21
no están en una lista de la aplicación 00:19:23
venga, pues entonces 00:19:25
seguimos, a ver que nos pasa aquí ahora 00:19:28
vamos a volver a ejecutar este main 00:19:30
para meter otro nuevo 00:19:32
vamos a meter otro nuevo 00:19:33
vale, entonces vamos a 00:19:35
volver a, vamos a 00:19:42
lanzar el main, nos va a pedir otro alumno 00:19:43
vamos a meter otro nuevo 00:19:46
como 00:19:48
guardar alumno tiene la opción 00:19:49
de añadir a true 00:19:52
nos agregará ese alumno 00:19:53
después del que hubiera de antes 00:19:56
no lo borra de nuevas, vale, después del que hubiera 00:19:58
de antes, pues venga, vamos a 00:20:00
agregar otro y vamos a volver 00:20:02
y vamos a volver a buscar el de nombre 00:20:04
1, 2, 3, 4, por el de nif1, 2, 3, 4 00:20:06
O el que sea, vamos a volver a buscar 00:20:08
A ver si nos lo encuentra ahora 00:20:09
Pues venga, ejecutamos el main 00:20:11
Este es el alumno 00:20:13
Que me está pidiendo, vamos a meter 00:20:18
1, 5, 6, 7, 8 00:20:19
Nombre este, vale 00:20:20
Continuar, no, uno más solo 00:20:23
No quiero continuar 00:20:25
Ahora tendrá dos, se supone 00:20:26
1, 2, 3, 4, 5, 6, 7, 8 00:20:29
Vamos a buscar el 1, 2, 3, 4 de antes 00:20:30
No me tendría que haber funcionado 00:20:33
Claro, porque en el primero 00:20:39
Todavía no se ha roto 00:20:48
Vale, bueno 00:20:49
Sí, vamos a volverlo a 00:20:51
Ya ha terminado, ¿no? 00:20:53
Vamos a hacer otra prueba 00:20:55
Este caso de prueba lo ha pasado 00:20:56
Vale, vamos a hacer otro caso de prueba 00:20:58
Hasta luego, vamos a meter otro alumno más 00:21:01
Otro alumno más 00:21:06
8, 8, 8, 8. Venga, un tercer alumno. 00:21:07
Tenemos ya 00:21:11
tres alumnos. ¿Continuar? No, no. 00:21:11
Tenemos tres. Vamos a buscar 00:21:13
el 5, 6, 7, 8, que era el 00:21:15
segundo. Vamos a volver a buscar el primero. 00:21:17
El 5, 6, 7, 8. 00:21:19
5, 6, 7, 8. Vale. 00:21:21
Y efectivamente, sin 00:21:24
tener ni idea, sin saber 00:21:25
por qué, no nos lo ha 00:21:27
encontrado. Y nos dice 00:21:29
cabecera corrupta. 00:21:31
Y este error ya de nuevo 00:21:34
y que no lo conocemos, no sabemos a qué se refiere 00:21:35
con cabecera corrupta 00:21:37
bueno, vamos a ver qué ocurre, ver cómo arreglarlo 00:21:38
y ya todo esto de desalinización de objetos 00:21:42
ya lo dejamos al completo 00:21:43
para poder usarlo 00:21:44
para guardar y recuperar objetos y hacer con ellos 00:21:46
lo que nos dé la gana 00:21:49
y con algo así podríamos pasar de una base 00:21:50
de datos, si lo necesitamos 00:21:53
podríamos pasar de una base de datos, los objetos se van ahí 00:21:55
los recupero 00:21:57
vale, pues qué ha pasado aquí, cuál es el rollo 00:21:58
este 00:22:01
con el que nos hemos encontrado 00:22:02
vale, rotulamos 00:22:05
bueno, pues que hace el 00:22:46
great object, nosotros hemos hecho, teníamos un objeto 00:22:58
alumno 00:23:01
aquí nuestro objeto alumno con if y nombre 00:23:01
nuestro objeto a 00:23:04
entonces, hemos hecho 00:23:06
un great object, de este objeto 00:23:08
a, vale 00:23:14
vamos a poner que estamos en el primer great object 00:23:15
en el que el archivo todavía no existía 00:23:18
bueno, pues ha creado el archivo de nuevas 00:23:19
y el great object 00:23:21
que es cuando 00:23:24
al crear el archivo de nuevas, lo primero que hemos 00:23:25
hecho es hacer el 00:23:28
object output string 00:23:29
bueno pues el object output string lo primero 00:23:31
que hace cuando hago un archivo para escribir 00:23:35
lo primero que hace es 00:23:37
hacer una cabecera aquí, te hace 00:23:39
una cabecera el object output string y se 00:23:43
queda abierto para que a partir 00:23:45
de ahí todos los objetos vayan a partir 00:23:47
de la cabecera, hemos hecho 00:23:50
un great object de A pues ha ido ahí 00:23:51
que con este mismo 00:23:53
flujo sin cerrar hubiéramos escrito 00:23:55
otro, pues ese otro hubiera ido 00:23:57
ahí, todos a partir de la cabecera 00:23:59
cuando ya lo hemos cerrado, hemos hecho esto un close 00:24:01
pues se acabó 00:24:03
este fichero terminó, vale 00:24:05
ahora hemos vuelto a ejecutar el programa 00:24:07
otra vez hemos vuelto 00:24:09
a instanciar un object output string 00:24:11
asociado a este que ya existía 00:24:14
que ya existía 00:24:15
pues que es lo que hace, como lo hemos dado con la opción 00:24:17
de true, de añadir 00:24:20
lo que ha hecho ha sido 00:24:22
como es añadir 00:24:23
me coloco aquí, pues aquí en medio 00:24:26
cojo y planto otra cabecera 00:24:27
planta otra en medio 00:24:29
y ahí la ha plantado 00:24:31
cada vez que se hace un object output stream 00:24:33
él planta una cabecera 00:24:35
que el fichero está limpio, es fenomenal 00:24:37
la ha plantado al principio 00:24:39
que el fichero ya tenía cosas y le hemos dado a añadir 00:24:41
la planta aquí en medio 00:24:43
y luego ya se escriben los objetos 00:24:44
¿qué ocurre? que la única cabecera que tiene sentido 00:24:47
que exista, la única que tiene sentido 00:24:49
que exista, es la primera 00:24:51
la que te informa del tipo 00:24:54
de objeto que hay, para eso sus propiedades 00:24:55
el resto de cabeceras 00:24:57
lo que hacen es corromper el fichero 00:24:59
y lo estropean, porque ahora ya 00:25:01
si uno abre un 00:25:03
con object input string para abrir y se pone 00:25:04
a leer, el object input string 00:25:08
lee la cabecera del principio, una vez 00:25:09
y se acabó, y a partir de ahí se pone 00:25:11
a leer, y él espera 00:25:14
todo el rato alumnos, alumno, alumno, alumno 00:25:15
y de repente cuando llega aquí se encuentra 00:25:18
algo que no es un objeto alumno y dice, no entiendo nada 00:25:20
y ahí es cuando sale el error 00:25:22
este del string corrupted, bla bla bla 00:25:24
entonces, ¿cuál es el problema? 00:25:26
que cuando abrimos con object output stream 00:25:29
para añadir 00:25:32
para añadir 00:25:33
tenemos que hacer algo 00:25:34
para que este object output stream 00:25:36
no escriba esto y se lo salte 00:25:39
tenemos que hacer algo para que no lo escriba y se lo salte 00:25:41
solo en ese caso 00:25:43
en el caso de que abramos 00:25:45
object output stream para añadir 00:25:47
en un fichero que ya existe 00:25:49
si lo hacemos en un fichero que no existe 00:25:50
entonces no, queremos que lo escriba 00:25:53
pero si es en un fichero que existe 00:25:55
tenemos que hacer algo 00:25:57
¿y ese algo cómo lo hacemos? 00:25:58
bueno, pues como sabemos cómo va esto de la herencia 00:26:00
y no sé qué, pues vamos a hacer un truco rápido 00:26:02
vamos a hacerlo 00:26:04
vale 00:26:06
vale, pues vamos a hacernos 00:26:08
una clase 00:26:33
object output string nosotros 00:26:34
que sea igualita 00:26:36
que la verdadera, que la real igualita 00:26:38
pero que lo único 00:26:41
que haga sea cambiar el método 00:26:42
de escribir cabecera para que ahí 00:26:44
no haga nada 00:26:46
entonces vamos a hacernos lo siguiente 00:26:47
vamos a hacernos 00:26:50
en el paquete este en el que estamos de objetos 00:26:53
vamos a hacernos una clase object output string 00:26:54
copia de la otra 00:26:57
pero que solamente cambio 00:26:58
de escribir cabecera para que no lo escriba 00:27:00
y en cada momento decidimos 00:27:02
si nos interesa usar la original 00:27:05
o la modificada 00:27:06
vale, pues vamos a hacernos entonces 00:27:08
una clase 00:27:10
la vamos a llamar object output string 00:27:11
sin cabecera, como lo queráis llamar 00:27:14
porque es nuestra 00:27:16
sin cabecera, venga 00:27:17
entonces como queremos que sea igualita que la otra 00:27:26
la forma de hacerla igualita 00:27:29
es haciendo la heredera de la otra 00:27:31
porque coge todo lo de la de arriba 00:27:33
pues la vamos a hacer 00:27:34
heredera de object output 00:27:37
voy a pasarlo aquí abajo 00:27:39
heredera de 00:27:41
object output stream 00:27:43
a la heredera de esta 00:27:45
entonces al ser heredera 00:27:48
de esta 00:27:50
que ocurre 00:27:52
que hereda todo, todo es una copia 00:27:55
calcada de la otra 00:27:57
menos el constructor, los constructores no 00:27:59
pues entonces vamos a hacer un constructor específico 00:28:01
a esta, vamos a hacerlo 00:28:04
un constructor específico 00:28:07
público, claro 00:28:09
que use 00:28:13
la de arriba 00:28:16
pero el constructor de object output string 00:28:18
que recibía, el constructor 00:28:21
de object output string 00:28:23
lo hemos usado aquí 00:28:24
object output string 00:28:26
recibe 00:28:31
un file output string 00:28:32
pues este también tiene que recibirlo 00:28:34
entonces 00:28:36
vamos a ponerle 00:28:37
esto 00:28:40
string 00:28:42
y vamos a hacer que este constructor 00:28:47
llame al de arriba y ya está 00:28:50
pasándole eso 00:28:52
y aquí esto me dice 00:28:57
que importe 00:29:03
pues importo 00:29:04
y aquí que importe 00:29:05
Vale, y aquí me dice que puede lanzar una excepción, pues la propago. 00:29:10
Vale, pues ya le he hecho un constructor que hace lo mismo que el constructor de arriba. 00:29:22
Lo mismo, el parámetro que yo le pase aquí, se lo pasa a este. 00:29:26
Entonces esta clase y esta son calcadas. 00:29:30
Vale, pero yo esta la quiero modificar para que el método que tiene esta, 00:29:34
que es el que utiliza para escribir la cabecera, pues que ese método está vacío, para que no escriba nada. 00:29:39
Y así tengo una versión de esta 00:29:43
Que en el momento de escribir la cabecera 00:29:46
No escriba nada 00:29:48
Bueno, vamos a sobreescribir el método 00:29:50
Escribir cabecera 00:29:52
Ese método no tendría que buscar a ver cuál es 00:29:53
Y si uno busca 00:29:56
Pues encontraría que ese método 00:29:58
Creo que se llama así 00:30:00
Si no lo comprobamos poniéndolo de raíz 00:30:05
Esto public 00:30:07
Void 00:30:13
Vale 00:30:16
Vale, ¿cómo puedo yo asegurarme 00:30:17
de que este método no es uno que yo 00:30:21
me he inventado, sino que sobrescribe 00:30:22
uno de arriba. 00:30:25
Aparte de porque el eclipse pone el triangulito 00:30:27
verde, aparte de porque 00:30:29
me lo pone, que eso dependería del entorno de desarrollo. 00:30:30
Lo que no depende del entorno de desarrollo 00:30:33
es si yo pongo la anotación 00:30:35
y pongo esto. 00:30:36
Si yo pongo la anotación 00:30:39
y no peta nada, 00:30:40
es que efectivamente este 00:30:43
método existe en la clase de arriba. 00:30:44
Porque si yo me hubiera equivocado 00:30:47
y hubiera puesto este, que esto significa 00:30:49
método nuevo y pongo 00:30:50
el overrack y me dice, uh, este método no 00:30:52
sobrescribe nada de arriba 00:30:54
si quito la anotación ya sí que no pasa nada 00:30:56
me echo uno nuevo y ya está, no pasa nada 00:30:58
pero la anotación me permite 00:31:00
comprobar 00:31:03
que este método que yo he puesto realmente 00:31:04
sobrescribe alguno de arriba 00:31:06
vale, pues writeStringHeader 00:31:08
por el nombre 00:31:11
deducimos que este es el método 00:31:12
que llama object.putString 00:31:14
cuando quiere escribir la cabecera 00:31:16
y yo quiero que esta versión 00:31:18
mía, quiero que esta versión no escriba 00:31:20
nada, cuando llame a ese método, que no escriba 00:31:22
nada, pues entonces lo dejo así 00:31:24
vacío 00:31:26
pues ya tengo dos versiones de 00:31:26
object output string, la que escribe cabecera y la que no 00:31:29
¿cuándo uso 00:31:32
una? ¿cuándo uso 00:31:34
la que escribe cabecera? 00:31:36
cuando mi archivo lo escriba limpio 00:31:38
desde arriba, ¿cuándo uso la otra? 00:31:40
cuando lo que quiera sea añadir 00:31:42
¿vale? entonces si el fichero 00:31:44
ya existe, uso 00:31:46
la nueva y si el fichero no existe 00:31:48
uso la original 00:31:50
vale, ¿cómo 00:31:53
modificaría eso nuestra aplicación? 00:31:54
pues en guardar alumno 00:31:57
en guardar alumno yo tengo que ver si el 00:31:58
fichero en el que voy a guardarlo 00:32:00
existe de antes de alumnos o no existe 00:32:02
porque si no existe 00:32:04
lo creo con 00:32:07
este para que cree cabecera y todo eso 00:32:08
pero si existe de 00:32:10
antes, entonces tengo que 00:32:12
abrirlo con la otra clase para que 00:32:14
no meta la cabecera, porque lo que voy a hacer es 00:32:16
añadir. Entonces tendríamos que hacer aquí un if 00:32:18
previo y decir, vamos a ver 00:32:21
vamos a hacer un objeto file para ese archivo 00:32:24
new file, fichero 00:32:27
alumnos. Vale, y vamos a ponernos aquí 00:32:35
la referencia object output 00:32:41
stream, que ahora mismo no tiene 00:32:44
nada, en la que yo voy a guardar un objeto 00:32:47
de una clase o de la otra. Pues me pregunto 00:32:53
vamos a ver, este fichero f 00:32:56
ya existe 00:32:58
porque si este fichero 00:33:00
f existe 00:33:07
entonces yo voy a abrirlo 00:33:08
para añadir 00:33:11
y no quiero meter cabecera 00:33:12
pues en ese caso 00:33:14
lo que querré guardar 00:33:16
en la referencia esta de aquí 00:33:19
será un objeto 00:33:20
de la clase obviedad put string 00:33:23
sin cabecera, el que me he hecho yo 00:33:25
este 00:33:27
para añadir 00:33:28
y por supuesto por la herencia 00:33:32
ya sabemos, yo puedo guardar 00:33:36
un objeto de este tipo en esta referencia 00:33:38
porque he hecho que esta era la de este otro 00:33:40
entonces este 00:33:42
objeto cae en esta referencia sin problema 00:33:44
vale, esto si el fichero 00:33:46
existe 00:33:48
pero si el fichero no existe 00:33:49
entonces 00:33:52
mi referencia esta 00:33:54
se llenará con un objeto del original 00:33:56
porque en ese caso hay que hacer la cabecera 00:33:58
porque no existe, etc 00:34:00
pues en este caso 00:34:01
este será un new 00:34:04
todo esto, pero del 00:34:06
control c 00:34:08
será todo esto 00:34:10
pero este será 00:34:14
sin cabecera 00:34:17
será el original 00:34:18
y de aquí quito el true, porque no voy a añadirlo, estoy haciendo de nuevas 00:34:20
y ya está, apañado 00:34:23
¿vale? 00:34:29
esta llave la voy a quitar 00:34:35
también si quiero 00:34:37
ala, pues ya está, ya está arreglado ese problema 00:34:38
que el fichero existe 00:34:43
lo abrimos 00:34:46
de tal manera que no meta cabecera 00:34:49
y se ponga a escribir los objetos 00:34:50
y más, que el fichero no existe 00:34:53
lo abrimos de tal manera que meta cabecera 00:34:55
y ya está 00:34:57
escribimos el objeto y cerramos 00:34:58
vale, pues ahora ya voy a 00:35:00
borrar el fichero de antes, porque ese ya se ha quedado 00:35:06
ese ya estaba roto 00:35:08
pues lo vamos a borrar 00:35:09
y ahora vamos a volver 00:35:12
a ejecutar el programa 00:35:18
este de aquí 00:35:19
objetos main 00:35:25
este main era 00:35:30
con el bucle 00:35:32
venga, no hay fichero 00:35:35
vamos a meter 1, 1, 2, 3, 4 00:35:41
nombre Pepito 00:35:43
vale, vamos a meter otro más 00:35:45
entonces 00:35:47
aquí llegaría el problema 00:35:49
si no hubiéramos hecho el arreglo que hemos hecho 00:35:50
porque al meter el otro 00:35:53
sin el cambio que hemos hecho 00:35:54
en el otro ya se habría metido también una cabecera 00:35:56
pero con el arreglo que hemos hecho ya no va a haber problema 00:35:59
vamos a meter otro 00:36:01
5, 6, 7, 8 00:36:03
Venga, y vamos a meter un tercero 00:36:04
9, 9, 9, 9 00:36:09
¿Queremos más alumnos? No 00:36:11
Se supone que hay tres alumnos metidos 00:36:14
Vamos de hecho a verlo 00:36:17
Aunque no sé si me va a dejar refrescar 00:36:21
Alumnos 00:36:25
Tiene ahí Pepito 00:36:28
El Juan y el Luis este 00:36:33
los tiene ahí, ya está cerrado 00:36:37
y ya está 00:36:39
vamos a ver si ha metido las cabeceras entre medias o no 00:36:39
como haya metido las cabeceras entre medias 00:36:42
cada vez que escribe un objeto 00:36:44
no va a funcionar el main 00:36:45
vamos a, venga, vamos a buscar 00:36:48
al último 00:36:51
pues sí que está 00:36:52
vamos a buscar ahora al 00:36:55
ah no, que ya acaba el main, no está en un bucle 00:36:57
o no puedo buscar más 00:37:00
vale, pues ya está, ya tenemos todo arreglado 00:37:01
y todo lo que necesitamos 00:37:04
no necesitamos 00:37:06
en realidad ni más métodos 00:37:08
de estas clases, ni conocer más nada 00:37:09
para trabajar con objetos 00:37:11
directamente en un fichero 00:37:13
aquí yo no los tengo en lista 00:37:15
no los tengo en nada, este main 00:37:17
inserta alumnos 00:37:19
los recupera, podría hacer mil cosas 00:37:23
modifica nombre, podría hacer mil historias 00:37:25
y los alumnos no están en el fichero 00:37:28
perdón, no están en una lista 00:37:30
están ahí 00:37:31
¿a qué parte? 00:37:32
Pues venga, vamos a hacer esta 00:37:57
Vale, esta funcionalidad 00:38:25
Aquí 00:38:31
Esto se complica un poco más 00:38:33
Porque tenemos que 00:38:35
Leer y escribir 00:38:36
En principio uno pensaría que simultáneamente 00:38:38
Porque primero, del archivo hay que leer 00:38:41
Sí o sí, porque hay que ir leyendo 00:38:43
Hasta llegar al alumno cuyo NIF sea ese 00:38:45
y una vez que hemos llegado 00:38:47
con el archivo abierto para lectura 00:38:50
y leyendo, resulta que hay que escribir 00:38:52
ese objeto otra vez, hay que escribirlo 00:38:54
de nuevas 00:38:56
porque hay que escribir el objeto con el nombre cambiado 00:38:56
entonces, hemos dicho que 00:39:00
o leemos o escribimos, pero las dos cosas no 00:39:01
entonces, ¿qué tendríamos que hacer? 00:39:04
podemos hacerlo de muchas maneras 00:39:06
vamos a hacer la forma más cómoda 00:39:07
me los leo todos, los llevo a una lista 00:39:09
ahí lo cambio y otra vez la lista para allá 00:39:11
pero claro, efectivamente es menos eficiente 00:39:13
si tengo 50.000 00:39:16
o 50.000 y todo es para allá, pues no 00:39:17
otra manera es trabajar directamente 00:39:19
con archivos a través de un archivo 00:39:21
intermedio, que es 00:39:23
leo de 00:39:25
tengo mi archivo de lectura 00:39:27
y mi archivo final 00:39:29
entonces, leo 00:39:31
es el que tengo que modificar, lo escribo tal cual 00:39:33
leo, es el que tengo que modificar 00:39:35
lo escribo tal cual 00:39:37
leo, es el que tengo que modificar, sí, este sí es 00:39:38
pues lo escribo con la modificación 00:39:41
y entonces ya en el 00:39:43
fichero destino 00:39:45
estará el resultado final 00:39:47
¿vale? 00:39:50
lo que pasa es que ese fichero de estilo tendrá otro nombre 00:39:51
no es la idea, pues lo que nos faltará será 00:39:53
eliminar este y a este cambiarle de nombre 00:39:55
y se acabó 00:39:57
y entonces el efecto final es como si hubiéramos 00:39:58
leído y escrito a la vez, pero no, hemos leído de uno 00:40:01
escrito en otro con las 00:40:03
modificaciones y luego hemos eliminado el original 00:40:05
y cambiado el nombre a este 00:40:07
entonces, esto sería 00:40:08
tendríamos que 00:40:11
abrir para leer 00:40:13
el archivo este 00:40:14
Abriríamos para leer 00:40:19
El fichero alumnos 00:40:23
Y esto me lanzaría 00:40:24
Una excepción, pues Alan 00:40:27
¿Te molesta la operación? 00:40:28
00:40:36
Vale 00:40:36
Y ahora vamos a hacernos uno temporal para escribir 00:40:41
Este lo vamos a escribir 00:40:47
Desde arriba, enterito 00:40:50
Uno temporal 00:40:52
Para escribir 00:40:54
Pues nada 00:40:55
y aquí le damos cualquier nombre, nos da igual 00:41:01
si luego se lo vamos a cambiar 00:41:18
es el fichero temporal 00:41:19
que va a tener el resultado final 00:41:24
y ahora ya 00:41:27
leemos de uno y escribimos en el otro 00:41:28
lo habrá que hacer, pues el bucle de lectura 00:41:30
otra vez enterito 00:41:33
pues venga, vamos a ponernos un fin archivo 00:41:34
igual a falso 00:41:37
Y ahora, mientras no hayamos llegado a fin archivo, pues ahora vamos leyendo alumno por alumno. 00:41:39
Ahora, ¿este alumno es el alumno de búsqueda que estamos buscando? 00:42:08
Pues vamos a ver. 00:42:17
¿Este alumno resulta que es igual al que estamos buscando? 00:42:21
si es igual al que estamos buscando 00:42:26
lo escribimos tal cual 00:42:32
a temp 00:42:34
entonces ya lo escribimos tal cual 00:42:35
ah perdón, no lo escribimos tal cual 00:42:38
lo escribimos modificado, o sea, si este es el que hay que 00:42:47
estoy, ahí 00:42:49
si este es el que hay que 00:42:51
modificar 00:42:56
pues entonces 00:42:58
a este objeto a 00:43:00
le vamos a poner el nuevo nombre 00:43:02
el nuevo nombre, que es este nuevo nombre 00:43:03
y ahora ya lo escribimos 00:43:06
ya está 00:43:08
entonces 00:43:10
le escribe 00:43:12
le escribe, le escribe 00:43:15
de uno se copia en otro 00:43:17
de uno se copia en otro, le escribe, le escribe 00:43:18
pero solo hay una salvedad 00:43:21
si el que ha leído es el que hay que modificar 00:43:22
antes de escribirlo 00:43:25
de nuevas, antes de escribirlos 00:43:27
le cambia el nombre y ya está 00:43:28
y ahora podríamos aprovechar 00:43:30
ya aquí dentro de este 00:43:35
if, poner esto a true 00:43:37
Para que no esté comprobando ya 00:43:39
Ah no, es que los demás los tiene que escribir también 00:43:41
Esto lo necesitamos 00:43:43
Perdón 00:43:45
Uno cualquiera 00:43:46
Porque es uno temporal 00:43:53
Vale, entonces 00:43:55
Le escribe, le escribe, le escribe 00:44:00
Y simplemente 00:44:02
Si el que ha leído es el del NIF correspondiente 00:44:03
Le cambia el nombre antes de escribir 00:44:07
Y ya está 00:44:08
Y todo esto habrá que meterlo en un try-catch, claro 00:44:10
habrá que meterlo en un try-catch 00:44:12
para que si ha llegado a la excepción 00:44:16
pues entonces 00:44:20
si hemos llegado a la excepción 00:44:26
eof 00:44:28
excepción 00:44:32
pues si hemos llegado a la excepción 00:44:40
pues entonces 00:44:42
fin archivo igual a 00:44:44
true 00:44:48
bueno pues este código 00:44:48
hará la modificación pero la dejará en temp 00:44:53
el otro lo deja tal cual 00:44:55
vale, pues entonces 00:44:57
ahora nos tocará borrar uno y cambiar de nombre 00:44:59
el otro, pero para eso tenemos los métodos de file 00:45:01
entonces antes que nada vamos a cerrar 00:45:04
los flujos de estos 00:45:06
el oiz y el temp, estos los vamos a cerrar 00:45:07
y ahora vamos a crearnos un objeto 00:45:09
file asociado a cada uno de ellos 00:45:22
un objeto 00:45:24
el original 00:45:26
este va a ser un new file 00:45:27
de el nombre archivo 00:45:33
archivo alumnos 00:45:35
archivo alumnos, no se llamaba archivo alumnos 00:45:36
yo creo que lo he llamado aquí fichero alumnos 00:45:44
¿verdad? 00:45:46
sí, fichero alumnos 00:45:47
fichero alumnos 00:45:49
y ahora, el destino 00:45:55
el temporal 00:46:01
es este 00:46:03
asociado al nombre temp 00:46:07
¿y ahora qué queremos? 00:46:09
vamos a borrar el primero de todos 00:46:15
para eso tenemos 00:46:17
original.delete 00:46:19
ala, el original ya está borrado 00:46:22
y ahora 00:46:25
a este temporal le queremos 00:46:27
cambiar el nombre 00:46:29
temporal.entonces hay un 00:46:30
rename to 00:46:34
donde te dice 00:46:35
dime un objeto file asociado al 00:46:37
nombre que tú quieres 00:46:41
bueno, pues ya este directamente 00:46:41
vale, hemos borrado el original 00:46:44
y al temporal le hemos cambiado 00:46:48
para que tenga como nombre el que está asociado 00:46:50
a este, que es el fichero alumnos 00:46:52
Y esto es lo que funciona o no, a veces depende del sistema operativo. 00:46:54
No he acabado yo nunca de ver muy claro cuándo funciona y cuándo no. 00:46:59
Pero vamos a probarlo. 00:47:03
Venga, vamos a, si no lo veremos en temp, la modificación. 00:47:05
En nuestro main vamos a comentar, nuestro main ya tenía alumnos, 00:47:10
que los hemos buscado, que funcionaban. 00:47:15
Entonces vamos a comentar todo lo que tenía para no seguir perdiendo tiempo con esto. 00:47:18
Y ahora vamos simplemente a 00:47:24
Tratar de modificar el nombre de un alumno 00:47:28
A ver si lo hace 00:47:29
Entonces 00:47:30
Este se llamaba 00:47:33
ModificaNombre 00:47:35
ModificaNombre 00:47:37
Y recibía el nif a modificar 00:47:41
Este que existía 00:47:44
Es el primero que metimos 00:47:46
El nuevo nombre, vale 00:47:47
Y ahora el fichero 00:47:49
Donde están esos alumnos 00:47:54
Que se llama así 00:47:55
vale, entonces el fichero 00:47:57
alumnos 00:47:59
tenía nuestros objetos 00:48:00
pues todos estos, tenía uno, un dos, tres, cuatro 00:48:03
luego tenía 00:48:06
el cinco, seis, siete, ocho 00:48:08
luego tenía el nueve, nueve, nueve, nueve 00:48:09
y ya está, vale, pues venga 00:48:12
modifica nombre 00:48:16
vale, pues vamos a ver que ha hecho 00:48:17
le damos aquí a refresh 00:48:28
y temp ha desaparecido 00:48:30
con lo cual tiene pinta de que ha funcionado 00:48:39
a ver, tendríamos que leer 00:48:41
ahora, pero lo vamos a ver 00:48:43
así a ojo directamente 00:48:45
vamos a ver aquí el 1, 2, 3, 4 que le ha pasado 00:48:46
pues sí, efectivamente 00:48:49
lo ha cambiado 00:48:51
si ejecutáramos ahora este main 00:48:52
vamos a poner de este main 00:48:55
vamos a buscar ese nif, a ver si ahora me lo 00:48:57
muestra con el nombre de 00:48:59
Raquel, para verlo bien, no verlo con el 00:49:00
editor de texto 00:49:03
que es un poco chapuza 00:49:05
vale, voy a hacer de nuevo el main 00:49:06
pero solamente con 00:49:09
voy a buscar el 1, 2, 3, 4 00:49:10
a ver si 00:49:12
venga, 1, 2, 3, 4 00:49:13
que lo había modificado antes, efectivamente lo ha modificado 00:49:17
vale 00:49:20
pues entonces podemos insertar 00:49:21
si quisiéramos eliminar un alumno del archivo 00:49:26
lo mismo 00:49:29
tendría que ser un temporal 00:49:30
leemos, copiamos, leemos, copiamos 00:49:32
pero nos saltamos en la copia 00:49:34
nos saltamos en la copia 00:49:36
el del nif a eliminar, nos lo saltamos 00:49:37
entonces ya podemos hacer cualquier cosa 00:49:40
insertar el archivo 00:49:42
eliminar con un temporal 00:49:44
como hemos hecho de modificar 00:49:46
modificar como lo acabamos de hacer 00:49:47
y recuperar como lo acabamos de hacer 00:49:49
las cuatro opciones básicas 00:49:51
consultas, lecturas, modificaciones y borrados 00:49:53
pues las podemos hacer sobre el archivo de objetos 00:49:56
y no necesitamos 00:49:58
ni lista, ni colección, ni nada 00:50:00
todo el archivo más eficiente 00:50:01
y más, o sea, menos memoria gastada 00:50:04
¿vale? 00:50:06
podéis hacer vosotros este método 00:50:07
de eliminar un alumno 00:50:10
y ya tendríamos todas las funcionalidades 00:50:12
modificar, eliminar, insertar y recuperar 00:50:13
Podríais hacer aquí la funcionalidad 00:50:16
Elimina alumno 00:50:20
Dado nif 00:50:24
Y dado el fichero de alumnos 00:50:26
Pero vamos, este método sería idéntico al de modificar 00:50:30
Con la única diferencia es que aquí 00:50:44
Lo que hay que hacer es 00:50:47
Escribir si no coincide 00:50:49
Y si coincide no hacer nada 00:50:52
No escribirlo 00:50:53
¿Vale? O sea, sería un método idéntico al de arriba. 00:50:55
O sea, idéntico, salvo esto cambiaría simplemente, pero vamos, con una... 00:50:59
Vale, pues hacedlo y ya tendréis las cuatro funcionalidades. 00:51:04
Y ya entonces podemos trabajar con objetos ya no solo en colecciones, sino también en archivos. 00:51:07
¿Vale? Si no queremos mantenerlos todos ahí a mogollón. 00:51:14
Venga, pues ya está. 00:51:17
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
15
Fecha:
25 de mayo de 2024 - 18:00
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
51′ 20″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
289.77 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid