20251007 EjerDAO_1 - Contenido educativo
Ajuste de pantallaEl ajuste de pantalla se aprecia al ver el vídeo en pantalla completa. Elige la presentación que más te guste:
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
en
00:02:08
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
Sí
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
eh
00:09:22
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
Ay
00:10:31
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
sí
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
no
00:26:03
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