Saltar navegación

20251007 EjerDAO_1 - 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 7 de octubre de 2025 por Raquel G.

7 visualizaciones

Descargar la transcripción

Vale, que se me había olvidado. 00:00:03
Pues vamos a implementar entonces este método 00:00:06
que está asociado a un file output string, 00:00:08
file, que se llamaba esto, 00:00:20
fichero alumnos. 00:00:24
Entonces, aquí, vale, 00:00:36
aquí tendríamos que distinguir si el fichero existe o no. 00:00:57
En este caso, si el fichero no existe, 00:01:02
recordad que este flujo de salida lo crea, 00:01:04
lo crea y lo crea vacío. 00:01:07
¿Vale? Entonces aquí en principio 00:01:09
si es el primer alumno que introducimos 00:01:11
pues lo va a crear el fichero 00:01:13
con lo cual no tengo que preocuparme 00:01:15
y si no es el primer alumno 00:01:16
la idea es abrirlo 00:01:19
pero abrirlo para añadir. 00:01:21
Entonces, FileOutputString 00:01:23
por defecto, si no poníamos 00:01:25
un segundo parámetro, recordad 00:01:27
que el parámetro de añadir 00:01:29
lo ponía a falso. 00:01:31
Entonces, si en el caso de que exista 00:01:33
yo quiero abrir para añadir 00:01:35
lo tengo que poner específicamente. 00:01:37
vale, porque si no por defecto es 00:01:39
falso, que es, si ya existe 00:01:41
lo limpio y lo creo de nuevo 00:01:43
que no es lo que quiero que ocurra 00:01:45
claro, si, si, pero no vamos a hacer eso 00:01:46
entonces, ahora ya 00:01:52
ya tenemos 00:01:57
el fichero abierto 00:02:00
y este es el método 00:02:01
más fácil 00:02:04
vamos a escribir este objeto 00:02:04
el fichero 00:02:11
vale, entonces 00:02:12
Sería este método 00:02:23
Ahora vamos a probar 00:02:25
La aplicación 00:02:28
Para empezar a depurar errores 00:02:29
Que nos van a salir, o eso espero 00:02:31
Vale, vamos a hacer este rápido 00:02:33
Y así ya, bueno, tenemos estos tres 00:02:35
Se podrían, lógicamente 00:02:38
No hemos puesto muchos más métodos 00:02:39
Que irían aquí, pues, de eliminar 00:02:42
De mil cosas, pero bueno, eso 00:02:44
Sería hacer lo mismo una y otra vez 00:02:45
El de eliminar 00:02:47
Como podéis intuir, pues se llamaría 00:02:50
delete 00:02:51
o delete by nif 00:02:52
uno lo llama como le dé la gana, pero siempre 00:02:55
repito, intentamos 00:02:57
hacer aplicaciones que sigan unos criterios 00:02:58
un poquito 00:03:01
universales 00:03:02
vale, recuperar nota módulo 00:03:05
pues tendríamos que leer 00:03:07
al del 00:03:09
leer al del nif 00:03:10
y cuando lo tengamos devolver su módulo 00:03:13
o sea, sería el mismo método 00:03:15
que este, pero en lugar de devolver 00:03:17
el objeto entero 00:03:19
Devolver la nota del módulo correspondiente 00:03:21
Entonces, sería este mismo método 00:03:23
Pero en lugar de devolver el objeto 00:03:25
Uy, que este mismo método de aquí 00:03:28
Result 00:03:32
Yo aquí he puesto 00:03:34
Result 00:03:35
Return 00:03:37
Null 00:03:38
Y sería return result, lógicamente 00:03:39
Vale, pues entonces sería este mismo método de aquí 00:03:41
Y ahora modificamos lo que toque 00:03:45
Get nota módulo 00:03:50
Pues venga, si el fichero no existe o tiene tamaño cero, no hay ningún alumno ahí, pues entonces ahí ya sí que devolvemos null, ¿vale? 00:03:53
Entonces, bien pensado el devolver el envolvente, no el primitivo, ¿vale? 00:04:08
Normalmente por eso trabajamos con envolventes, no con primitivos, porque el envolvente admite la opción de ponerle null, ponerle nada, el primitivo no. 00:04:15
entonces si yo devuelvo el primitivo 00:04:23
tendría que devolver aquí un numerito siempre 00:04:26
que se podría confundir con la nota 00:04:28
aunque yo podría hacer un java2 que fuera 00:04:29
si devuelven menos 7 00:04:31
es porque no hay nota 00:04:33
pero ya eso es una cosa muy poco intuitiva 00:04:35
entonces le obligo al tío a mirar 00:04:38
el java2 a ver qué significa el menos 7 00:04:39
el null 00:04:41
es una cosa absolutamente intuitiva 00:04:43
cuando uno ve que su método devuelve null 00:04:45
es porque no ha podido obtener el dato 00:04:47
no porque el dato sea null 00:04:50
¿vale? 00:04:51
aún así el null es un poco feo 00:04:53
porque un método que devuelve null 00:04:57
es un riesgo de null pointer exception 00:04:59
si el de arriba no lo ha gestionado correctamente 00:05:01
entonces aquí lo ideal sería devolver 00:05:05
pero bueno, eso ya surgirá más adelante 00:05:08
en otras cosas para no mezclarlo todo 00:05:11
devolver otro envolvente de este 00:05:13
o sea, ya tenemos dos envolventes 00:05:15
al primitivo le envuelve este 00:05:17
y a este le envolvería una clase opcional 00:05:19
que es una cajita 00:05:22
en la que tú metes el objeto 00:05:24
si ese objeto es null 00:05:26
es una cajita que tiene null pero la cajita no es null 00:05:28
con lo cual tú no devuelves un null 00:05:30
y luego el de arriba al ver que devuelves 00:05:32
un optional pues ya 00:05:34
se ve forzado a acceder 00:05:36
dentro y de alguna manera le haces 00:05:38
consciente de que ahí puede haber un null 00:05:40
cuidado, es mucho más complicado que se genere 00:05:42
un null pointer exception, ya se tiene que emperrar 00:05:44
el de arriba en sacarlo del optional y llamar 00:05:46
al método para que salga un null pointer exception 00:05:48
Pero bueno, lo del optional 00:05:50
Como va a salir en más situaciones 00:05:53
No hace falta que pongamos aquí 00:05:56
Un optional integer por ahora 00:05:58
Vale, vamos a devolver la nota 00:06:00
Estábamos buscando al 00:06:02
Al chaval con este 00:06:04
NIF, ya lo habíamos encontrado 00:06:06
Y ahora ya, cuando teníamos al chaval 00:06:07
Con este NIF 00:06:10
Ahora lo que queremos es 00:06:11
La nota del módulo 00:06:13
Entonces 00:06:16
es una colección, vamos a sacarlo 00:06:17
a ver si lo sacamos rápidamente 00:06:23
el alumno A tendrá su lista de módulos 00:06:27
que es getModules, lo vamos a serializar 00:06:31
y de aquí queremos 00:06:37
quedarnos con un solo elemento, ¿verdad? 00:06:40
queremos quedarnos con el elemento de la lista de módulos 00:06:44
Cuyo nombre sea el que me han dado 00:06:48
Eso automáticamente, ¿qué método sería de stream? 00:06:49
Un filter 00:06:55
¿Vale? 00:06:56
Un filter 00:06:59
Entonces 00:07:00
Uy, a ver 00:07:01
Hacemos un filter 00:07:03
Lo paso abajo 00:07:06
¿Qué me ha hecho este? 00:07:07
A ver, yo quiero aquí un 00:07:10
A ver si me deja hacer el enter tranquilamente 00:07:12
00:07:14
Hacemos un filter 00:07:14
Al filter hay que pasarle una interfaz 00:07:16
O función lambda de tipo predicado 00:07:20
Que es, con cada elemento 00:07:22
Cada elemento del string 00:07:24
¿Cuál va a ser 00:07:26
True para nosotros? 00:07:29
O sea, claro 00:07:31
Nos vamos a quedar con aquel 00:07:32
Cuyo nombre 00:07:34
Sea igual 00:07:36
Al que nos han dado 00:07:38
Que es 00:07:40
Módulo 00:07:41
Nos vamos a quedar con este 00:07:43
Y hombre, siempre hacemos 00:07:47
La aplicación un poquito más 00:07:51
robustilla 00:07:52
si nos acostumbramos 00:07:55
en el equals de cadenas 00:07:57
a poner ignore case, a ver siempre y cuando 00:07:59
mi aplicación 00:08:01
esté diseñada 00:08:01
de esa manera, para que le dé igual mayúsculas 00:08:05
o minúsculas, porque es que 00:08:07
si es equals y el tío me ha metido 00:08:09
el módulo con tilde, no perdón 00:08:11
con tilde no, con tilde no sería 00:08:13
con mayúscula y yo lo tengo guardado 00:08:14
en mi base de datos, todo con minúscula 00:08:17
pues será un rollo de 00:08:19
aplicación, vale, pues entonces ya tenemos 00:08:21
el predicado 00:08:22
este 00:08:23
acaba aquí, vale 00:08:25
y ahora 00:08:28
¿qué queremos hacer con 00:08:30
ese elemento? con ese elemento 00:08:34
queremos solo 00:08:37
la nota, ese 00:08:39
elemento ahora mismo es un módulo 00:08:40
entero con su nombre y nota 00:08:42
pero solo queremos 00:08:44
quedarnos con la nota, luego 00:08:46
ahora ¿qué método tendríamos que 00:08:48
poner 00:08:50
de stream 00:08:51
quiero, vete abajo y un punto 00:08:53
queremos, ahora tenemos 00:08:59
una filita con un único elemento 00:09:00
bueno, en realidad podría ser con muchos si hubiera muchos 00:09:02
módulos que se llamaran igual, pero no es la idea 00:09:04
tenemos una filita con un único elemento 00:09:06
esa filita 00:09:08
tiene su nombre y su 00:09:10
módulo, ese único elemento 00:09:12
queremos quedarnos solo con su nota 00:09:14
porque es lo que hay que devolver 00:09:16
lo que dice el método, pues que 00:09:18
método pondríamos ahí de stream 00:09:20
pondríamos map 00:09:24
muy bien, voy a poner la nota 00:09:30
directamente y así no te examinas, es un coñazo corregir 00:09:32
vale 00:09:34
map, que tras el 00:09:35
objeto completo 00:09:38
lo lleva a 00:09:39
lo convierte en su nota, porque eso es lo único 00:09:41
que nos interesa, su nota, nada más 00:09:44
entonces map sería 00:09:46
mi objetito 00:09:47
completo 00:09:50
Conviértemelo a x.getNota 00:09:51
Vale 00:09:55
Y ahora 00:09:56
Todo esto de aquí 00:10:00
Todo esto de aquí 00:10:05
Yo lo quiero guardar en un ínteger 00:10:07
A ver si ya 00:10:11
Espera, vamos a poner el resultado 00:10:13
En este caso, el resultado 00:10:18
En este caso va a ser un ínteger 00:10:19
Con lo cual el resultado 00:10:21
Nada de ser alumno 00:10:23
Integer, lo que yo voy a devolver 00:10:24
Y ahora, todo esto de aquí 00:10:27
El objetivo es meterlo en un result 00:10:29
El objetivo es meterlo ahí, entonces 00:10:32
Vale, los paréntesis ya están, ¿no? 00:10:40
Vale, ah, no, no, no 00:10:45
Esto, que mal 00:10:46
Vale, vale, entonces 00:10:47
Ya lo he convertido con el 00:10:50
Map a 00:10:52
Esa fila de un único elemento 00:10:53
Podría ser muchos, pero vamos 00:10:56
va a ser de uno, acepto práctico 00:10:57
ya lo he convertido en una fila 00:11:00
de notas 00:11:02
pero el resultado del map sigue siendo 00:11:02
una fila, ¿vale? 00:11:06
sigue siendo una fila, ahora 00:11:07
me tengo que quedar 00:11:09
con alguno de los elementos de la fila 00:11:11
entonces algún método tengo que invocar 00:11:13
para quedarme con uno de ellos 00:11:16
entonces, en este caso 00:11:17
vamos a ver si hay algún método que me permita 00:11:19
quedarme con el primero, por ejemplo 00:11:22
o, pues sí 00:11:23
hay un findFirst, no solamente tiene un elemento 00:11:26
pues hay un findFirst 00:11:28
que se queda con el primero 00:11:30
de todos, y de hecho 00:11:32
ya detecta que va a ser un entero 00:11:34
porque el string que te ha dado 00:11:36
el map es de enteros 00:11:38
el string que te ha dado el map es de enteros 00:11:39
entonces findFirst 00:11:42
se devuelve en el primero, en nuestro caso 00:11:44
el primero es el que nos interesa 00:11:46
00:11:48
vale 00:11:52
y ya por último 00:11:55
este pues como es muy listo 00:11:56
te ha devuelto el primero 00:11:59
pero te lo han vuelto en el optional 00:12:01
vale, porque podría ser 00:12:03
un null o podría ser 00:12:05
porque está diseñada así 00:12:07
la interfaz, el frame 00:12:09
de streams este, está diseñada así 00:12:11
entonces te lo envuelve en un optional 00:12:13
vale, pues vamos a sacarlo del optional, no pasa nada 00:12:14
lo saco del optional para guardar un result que se entere 00:12:17
¿cómo se saca de un optional? 00:12:20
pues como no podría ser de otra manera 00:12:22
con el método get 00:12:24
ya lo he sacado del optional 00:12:25
y ya está 00:12:31
bueno pues ya tengo aquí 00:12:38
la nota 00:12:43
del alumno A 00:12:44
para el módulo correspondiente 00:12:47
que podía haber hecho esto 00:12:49
con un for, recorrer la colección 00:12:51
y cuando lo he encontrado, pues sí, podía haberlo hecho 00:12:53
con un for, pero es que esto 00:12:55
sale de corrido, tú serializas 00:12:57
Vas poniendo punto, vas seleccionando métodos 00:12:59
Y es que te sale mucho más de corrido 00:13:02
Que hacerlo con un for 00:13:03
¿Vale? 00:13:04
Aparte de lo bonito que queda 00:13:07
Bueno 00:13:09
Pues ahora ya 00:13:17
La nota del módulo se ha guardado en result 00:13:19
Y se devuelve aquí 00:13:25
Y se acabó 00:13:27
Vale, ya tenemos los tres métodos 00:13:28
Ahora ya podemos probar la aplicación 00:13:31
Y arreglar los tropecientos errores 00:13:33
que seguramente no salgan 00:13:35
dime 00:13:37
en lo que pasaste 00:13:38
no está lo de 00:13:40
adgestión de alumnos 00:13:41
solo hay 00:13:42
las carpetas de BIM y la de Logical 00:13:45
uy pero se 00:13:48
se comprimió el proyecto 00:13:49
pues nuestra 00:13:51
aplicación ahora sería 00:13:58
esto de aquí 00:13:59
con el menú 00:14:00
entonces vamos a insertar un alumno 00:14:03
mostrar la nota 00:14:05
de un alumno, recuperar un alumno y como esto no lo tenemos hecho, nuestra opción 3 va 00:14:07
a ser mostrar nota. Y así usamos solo lo que tenemos, mostrar nota. Vale, entonces 00:14:15
ahora lo que necesitamos es instanciar un objeto de acceso a datos. Lo necesitamos instanciar 00:14:29
Y ya está. Aquí en esta aplicación estamos directamente instanciando este objeto para llamar a sus métodos cada vez que tengamos que guardar lo que sea. Sobre esto muchas veces se hace otra capa más, que es una capa de servicio que trata de traducirlo a un idioma más humano. 00:14:37
entonces, la capa de servicio 00:14:57
sería a su vez una interfaz con métodos 00:15:00
como encuentra alumno, no sé cuántos 00:15:02
y esa capa de servicio 00:15:04
llamaría a esta, que es la que tiene 00:15:06
los nombres raros, pero bueno 00:15:08
aquí no estamos poniendo esa capa adicional 00:15:09
sino llamamos a esto directamente y ya está 00:15:11
pues venga, insertar alumno 00:15:13
en el caso 1 00:15:18
pedimos los datos del alumno 00:15:19
vamos a copiarlos de la otra 00:15:21
versión que también tendría 00:15:24
pedir datos alumno 00:15:25
de hecho 00:15:27
tenía un solicita datos, pues vamos a copiar 00:15:30
este método 00:15:32
solicita datos de la otra 00:15:33
versión 00:15:35
solicita datos era un método de aquí 00:15:36
que lo ponemos 00:15:42
también aquí abajo 00:15:47
y ahora aquí haríamos 00:15:48
alumno a 00:15:55
igual a solicita 00:15:58
datos 00:16:01
vale 00:16:04
Solicita datos 00:16:05
Y ahora 00:16:10
Se llama dao 00:16:15
La clase 00:16:17
Pues dao.save 00:16:18
Ala, ya está 00:16:20
Vale, entonces los detalles de cómo se hace el save 00:16:23
Nos dan igual 00:16:27
Los podríamos cambiar en un momento dado 00:16:28
Podríamos cambiar el fichero, podríamos cambiar cosas 00:16:30
Esta aplicación le da exactamente igual 00:16:32
Vale, el caso 2 00:16:34
Recuperar alumno 00:16:37
Pues recuperar alumno 00:16:39
Aquí sí que tendríamos que pedir el NIF 00:16:40
NIF alumno 00:16:42
Entonces, aquí 00:16:49
Aquí no tenemos un escáner 00:16:54
Así sí tenemos uno 00:16:57
Leemos el NIF del alumno 00:16:58
Y ahora ya tendríamos 00:17:03
A nuestro alumno A 00:17:06
Reutilizo esa variable A 00:17:07
Que sería 00:17:09
DAO 00:17:11
DAO 00:17:12
Find by NIF 00:17:13
Vale, y ahora 00:17:15
si a es 00:17:23
diferente de null 00:17:25
bueno, vamos a meterlo en un 00:17:27
si, si muestra null, muestra null, así no 00:17:29
engordamos esto, mostramos 00:17:31
a uno y ya está, que alumno creo que tenía 00:17:35
ya un toString, ya lo habíamos hecho 00:17:37
ala, pues este ya estaría 00:17:38
como hace 00:17:41
localizar por 00:17:43
clave primaria, no 00:17:45
lo sabemos y nos importa, es otro 00:17:47
problema que está desacoplado por otro lado 00:17:49
y ahora vamos a hacer lo último 00:17:51
Mostrar nota de módulo 00:17:53
Pues aquí habrá que pedirle 00:17:58
Nif alumno y nombre del módulo 00:18:00
Bueno, lo que pasa es que 00:18:02
Hola 00:18:03
Nif alumno 00:18:04
Y nombre de módulo 00:18:12
Y vamos a tener que añadir 00:18:18
Muy rápidamente otra funcionalidad 00:18:26
Que será insertarle módulo al alumno 00:18:28
Por eso no vamos a poder probar esta 00:18:30
Pues esto de aquí 00:18:31
No alteréis 00:18:41
Y ahora, ya aquí podríamos hacer un mostrar dao.getnotamódulo, con if y nombre módulo. 00:18:43
Y ya está. 00:19:02
Vamos a probar primero el insertar y recuperar. 00:19:08
Para probar el mostrar nota habría que añadir uno de insertar módulo a un alumno. 00:19:13
Que no lo tenemos todavía puesto 00:19:20
Entonces 00:19:22
DAO implementación 00:19:23
Tenemos 00:19:29
Primer problema 00:19:32
Aquí 00:19:34
Cuando arranque la aplicación 00:19:34
O sea, cuando hagamos la primera 00:19:37
Llamada a DAO 00:19:40
Aquí ya va a haber 00:19:42
Un problema, ¿no? 00:19:44
Que el fichero del mundo está sin inicializar, ¿verdad? 00:19:49
Claro, entonces 00:19:52
Aquí lo normal es que las clases 00:19:53
de implementación tengan un constructor 00:19:55
que inicialice la fuente de datos 00:19:57
entonces antes de esperar 00:19:59
que nos salga y no perder más tiempo 00:20:01
vamos a hacerlo y ya está 00:20:03
entonces esto inicializaría la fuente 00:20:04
de datos 00:20:15
si fuera una base de datos 00:20:16
pues ese método inicializaría la conexión 00:20:20
a la base de datos, lo que fuera 00:20:23
en este caso se inicializa 00:20:24
nuestro fichero y ya está 00:20:26
pero que ocurre que cuando arranca la aplicación 00:20:28
aquí 00:20:30
nos va a pasar una cosa muy fea 00:20:32
Que es que vamos a tener que pedirle al usuario 00:20:34
¿Cuál es el fichero? 00:20:36
Esta cosa tan fea la arreglaremos ahora después 00:20:37
Con un archivo de properties 00:20:39
Y así no tenemos que pedirle al usuario 00:20:41
Pero ahora mismo vamos a decirle 00:20:43
Cuando arranque la aplicación 00:20:45
El técnico, el que la despliega en el servidor 00:20:46
Tendrá que decir, este es el fichero de trabajo 00:20:49
Y ahora, fichero de alumnos 00:20:51
Pues tendremos que leerlo aquí 00:20:59
Bueno, ni siquiera hace falta 00:21:01
Vamos a ponerle el scan aquí 00:21:08
Y ya está 00:21:10
Y así no 00:21:11
New file 00:21:13
Y hacemos aquí un scan.nextline 00:21:14
Vale, pues ese error que nos hubiera salido de un null pointer exception 00:21:22
Al acceder al archivo ya no nos va a salir 00:21:30
Entonces 00:21:33
Venga, pues vamos a arrancar esto 00:21:35
Venga, ¿con qué fichera vamos a trabajar? 00:21:39
Vamos a trabajar con alumnos.dam2 00:21:49
Insertamos un alumno 00:21:52
NIF 1111 00:21:55
Nombre 1111 00:21:57
No sabemos insertarlo 00:21:59
Vamos a probar a recuperarlo 00:22:02
1111 00:22:03
El alumno es este 00:22:05
Vale 00:22:07
Vamos a insertar otro 00:22:08
2222 00:22:11
Nombre 2222 00:22:12
Vamos a ver si se ha insertado 00:22:16
2, recuperar alumno 00:22:19
Vamos a ver si el primero sigue 00:22:21
Y nos sale lo que nos imaginábamos e intuíamos del año pasado 00:22:22
¿Verdad? 00:22:27
Que lo arreglamos rápidamente 00:22:29
Me dice, uy, el stream del que estoy cogiendo los datos 00:22:31
O lo que es lo mismo 00:22:35
Los objetos serializados del fichero 00:22:36
Están muy corruptos 00:22:39
De hecho es un asco 00:22:43
Vale, ¿de dónde venía este problema? 00:22:43
Este problema venía 00:22:48
A ver si ha aparecido 00:22:49
este problema venía de que cuando 00:22:52
hacíamos un object output string 00:23:01
por primera vez 00:23:04
pues la máquina virtual 00:23:05
abría ese fichero para escribir 00:23:09
y le ponía aquí una cabecera 00:23:11
donde daba detalles del tipo de objeto 00:23:13
que iba a serializar 00:23:18
pues las propiedades que tenía todo 00:23:19
luego ya que hacíamos un write object 00:23:21
pues escribía el objeto 00:23:23
que hacíamos otro write object 00:23:24
Una vez que ya cerrábamos el flujo 00:23:26
Object-OutputString 00:23:30
Este cuchillo ya 00:23:31
Se quedaba cerrado y se acabó 00:23:32
Que volvíamos a abrirlo con Object-OutputString 00:23:35
Porque queremos añadir otro más 00:23:38
Queremos añadir otro 00:23:39
Pues se lo abría con Object-OutputString 00:23:40
Y si lo habíamos abierto con True 00:23:43
La opción de añadir la habíamos puesto a True 00:23:45
Pues se lo habría localizado 00:23:48
En este punto 00:23:50
Porque lo habría para 00:23:50
Añadir 00:23:53
no ve la cabecera. 00:23:54
Más que no ve, es que el obvio de 00:23:56
output stream, independientemente del 00:23:58
punto donde lo abra, si es al principio 00:24:00
porque le hemos dicho sobre escribir 00:24:02
o es al final, pero me he dicho de añadir, 00:24:04
independientemente de donde lo abra, él siempre, 00:24:06
así, de forma autómata, 00:24:08
sin pensar, él siempre te crea una cabecera. 00:24:10
Siempre. 00:24:13
Con lo cual, si tú abres el archivo 00:24:14
oye tu output stream, para 00:24:15
serializar, pero añadiendo, 00:24:17
te has cargado el archivo. 00:24:21
Porque la cabecera sólo 00:24:22
debe figurar aquí. No podemos meter cabeceras por medio. Entonces, lo que ha pasado aquí 00:24:24
es eso. Hemos creado un objeto y lo hemos serializado y se acabó. Ahora hemos vuelto 00:24:30
a meter a otro. Al meter a otro para añadir, ese otro, pues ha hecho que el objeto put 00:24:33
string meta aquí una cabecera y el segundo se ha metido aquí. Cuando ahora ya hemos 00:24:39
abierto con object input string, él ha leído la cabecera bien y ha empezado a leer el objeto. 00:24:43
El primero lo ha leído correctamente, pero luego cuando ha seguido leyendo, aquí ya 00:24:48
he encontrado datos que no son de objetos 00:24:53
sino que son datos que no entiendo 00:24:55
¿vale? 00:24:58
bueno, pues ¿cómo arreglábamos esto? 00:24:59
pues nos interesa una versión de 00:25:01
object output string 00:25:03
que no cree la cabecera 00:25:04
para usarla cuando vamos a añadir 00:25:06
¿vale? 00:25:10
y entonces eso, gracias a la herencia 00:25:11
pues lo hacíamos muy 00:25:13
rápidamente 00:25:15
eso, gracias a la herencia, pues hacíamos 00:25:16
a ver, para no 00:25:22
complicar con más paquetes, voy a meter 00:25:24
aquí dentro de lógica. Vamos a crearnos nuestra propia versión de object-output-string 00:25:26
pero que no cree cabecera. Voy a llamar a la primera o a esta en función de si el fichero 00:25:32
existe o no existe y ya está. Venga, pues aquí me hago mi clase. Quiero que sea un 00:25:45
object-output-string tal cual, idéntico al otro, que funcione igual, con lo cual voy 00:25:57
hacer que herede 00:26:02
o sea 00:26:18
tú lo puedes programar de otras maneras 00:26:19
pues 00:26:22
claro, cuando vayas a añadir 00:26:22
en lugar de añadir, leerlos todos 00:26:26
y volverlos a escribir 00:26:28
pero eso es muy chapuza 00:26:29
porque lees todos los objetos 00:26:31
y los tienes todos en memoria 00:26:33
entonces 00:26:36
gracias a que esta clase 00:26:36
no es final, podemos hacer 00:26:39
el extens, claro, si fuera final 00:26:41
recordad que no se puede heredar de una clase final 00:26:42
vale, entonces queremos 00:26:44
que sea igualita, igualita en todo 00:26:46
salvo 00:26:48
en un método 00:26:50
que sea, bueno, primero vamos a importar esto 00:26:51
putString 00:26:54
vamos a 00:27:03
hacer el constructor ahora 00:27:14
pero lo único que queremos que cambie 00:27:16
esta clase respecto a aquella que 00:27:18
sobreescribimos, lo único que queremos que cambie es el método de escribir cabecera 00:27:20
que queremos que no haga nada. Pues vamos a sobreescribir, y aquí es importante poner 00:27:25
el override para asegurar que estamos acertando con el método, el método de object.putString 00:27:29
que escribe la cabecera. Entonces, este método, creo recordar, y si no, lo buscamos, que se 00:27:34
llamaba writeStream 00:27:44
header. Debe ser 00:27:47
que sí que se llama así, porque 00:27:52
si no se llamara así, me habría 00:27:54
saltado con el overwrite. 00:27:56
¿Vale? Por eso es importante poner el overwrite. 00:27:58
Para asegurarme de que no me estoy 00:28:00
inventando otro, sino que estoy 00:28:02
sobreescribiendo de arriba. 00:28:04
O sea, que el método write a secas llama también al método 00:28:05
writeStream. 00:28:07
No, la instanciación, 00:28:12
el constructor del object output. 00:28:14
Luego el writeObject escribe el objeto, 00:28:17
pero cuando tú creas el object outputStream, 00:28:19
claro, mete la cabecera 00:28:20
vale, entonces debe ser que si existe un método 00:28:22
que se llama así, que por su nombre 00:28:24
deducimos que escribe la cabecera 00:28:26
pues este en blanco 00:28:28
este en blanco, vale 00:28:29
y con el constructor que podemos hacer, pues cuando 00:28:32
instanciemos este de aquí 00:28:34
lo queremos hacer 00:28:36
apoyándonos en el constructor del de arriba 00:28:38
pero es que nuestro uso 00:28:40
del constructor del de arriba 00:28:42
es de todas las versiones 00:28:44
que tiene, está aquí 00:28:46
el constructor 00:28:48
la versión que estamos usando del constructor desde arriba 00:28:49
es la que le pasas el flujo, pues vamos 00:28:53
a apoyarnos en ese 00:28:57
entonces vamos a apoyarnos en ese al cual le pasamos 00:29:00
un file output string 00:29:05
que le vamos a pasar desde aquí también, vale, repito 00:29:09
como esta es la versión del constructor que estamos usando 00:29:25
que es la versión del constructor de arriba 00:29:29
al que le pasas el fichero 00:29:31
pues nuestra versión 00:29:33
del constructor le vamos a pasar el fichero 00:29:35
y él se lo va a pasar, se va a apoyar en el de arriba 00:29:37
y va a pasarse al de arriba 00:29:39
la única diferencia entonces entre este y el otro 00:29:40
es que este no escribe cabecera 00:29:43
todo lo demás funciona exactamente igual 00:29:45
entonces vamos a parar unos minutos 00:29:47
pero lo único que nos faltaría 00:29:50
es cambiar en el escribir archivo 00:29:51
que existe 00:29:54
uso este, que no existe uso el otro 00:29:55
y se acabó 00:29:57
¿Vale? 00:29:59
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Segundo Curso
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
7
Fecha:
7 de octubre de 2025 - 13:43
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
30′ 01″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
137.28 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid