Saltar navegación

Clase 24-05-24 - 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 25 de mayo de 2024 por Raquel G.

11 visualizaciones

Descargar la transcripción

su capa más básica para acceder a ficheros 00:00:02
su capa más básica trabaja en dos modos 00:00:07
el modo carácter que es asumiendo que el fichero lo que tiene es texto 00:00:10
es decir, que esos bits que tiene 00:00:15
si los agrupamos de 8 en 8 tiene una correspondencia en la tabla ASCII 00:00:17
que representa un carácter 00:00:22
o el modo byte 00:00:23
o el modo byte 00:00:25
entonces en el modo byte 00:00:27
no hacemos ninguna 00:00:35
suposición sobre el contenido del archivo 00:00:36
asumimos que un archivo 00:00:39
es una lista de ceros y unos 00:00:40
y lo que codifique 00:00:43
pues vete a saber, dependerá de la aplicación 00:00:44
que lo haya generado, si lo ha generado el Word 00:00:47
pues codificará 00:00:49
la codificación 00:00:51
interna del Word, sea la que sea 00:00:53
si lo ha generado el Excel, pues la codificación interna 00:00:54
del Excel, un fichero al fin y al cabo 00:00:57
es eso, es una sucesión de bits 00:00:59
uno tras otro, entonces en algunos 00:01:00
casos 00:01:03
esos bits si los agrupamos de 8 en 8 00:01:03
hacemos la correspondencia con 00:01:07
la tabla ASTI, vemos 00:01:09
un texto con sentido 00:01:10
y eso es un fichero de texto 00:01:12
pero en muchísimos otros casos 00:01:15
esa ristra de bits 00:01:17
no se corresponde con caracteres 00:01:18
de la tabla ASTI, sino se corresponde 00:01:21
con lo que 00:01:23
la aplicación haya generado para 00:01:25
guardar su propia información 00:01:26
y toda esa rista de bits 00:01:28
para que sea interpretable 00:01:30
es esa misma aplicación 00:01:32
Word, Excel, la que sea esa misma 00:01:34
la que lo tiene que abrir, porque si no 00:01:36
es imposible entender de ahí nada 00:01:38
entonces 00:01:40
Java ofrece unas clases 00:01:42
para, asumiendo que los bits 00:01:44
vienen de donde vengan, simplemente 00:01:46
dedicarse a moverlos 00:01:48
moverlos a 00:01:50
memoria principal o volverlos a llevar 00:01:52
al fichero, pero no valen para nada más 00:01:54
porque no puede extraer ninguna información sobre esos bits 00:01:56
no puede extraer ninguna, no valen para nada más 00:01:58
entonces las voy a mencionar solo para que las conozcamos 00:02:00
porque son las básicas sobre las que se monta todo 00:02:03
y esas clases básicas sirven simplemente 00:02:06
para mover bits de 8 en 8 00:02:09
de nuestro fichero a variables de Java 00:02:12
y para volverlas a llevar de variables de Java aquí 00:02:15
y solamente valen para eso 00:02:18
luego ya esos bits que están ahí movidos ya en variables de Java 00:02:20
si esa aplicación Java 00:02:23
tiene información sobre lo que le significan 00:02:26
son de Word, son de no sé qué 00:02:28
puede plantearse hacer cosas con ellos 00:02:30
si tiene esa información añadida sobre lo que significan 00:02:31
pero si no, son 8 bits que no significan 00:02:33
nada para ella 00:02:36
para la aplicación Java, no significan 00:02:37
porque tienen una codificación que depende 00:02:40
de la aplicación 00:02:42
¿vale? entonces 00:02:43
repito, voy a mencionarlas porque son 00:02:45
las básicas o las que se montan todas las 00:02:48
demás, pero 00:02:50
su uso es simplemente ese 00:02:51
coger de un fichero, que son 00:02:53
un montón de bits, mover los bytes 00:02:55
de uno en uno a la aplicación 00:02:58
a variable y ya está 00:02:59
bueno, pues esas clases, las que trabajan 00:03:01
en modo byte 00:03:03
serían estas 00:03:05
file input 00:03:07
stream, para leer 00:03:10
es decir, cuando digo leer 00:03:18
digo mover del fichero 00:03:20
a variables de java 00:03:21
y file output stream para escribir 00:03:23
vale, pues entonces repito 00:03:26
vamos a ver un ejemplo mínimo de cómo 00:03:37
funcionan, pero entendiendo que 00:03:39
su uso 00:03:41
es muy muy muy limitado, porque lo único que hacen 00:03:42
es mover, entonces a lo mejor ¿para qué nos pueden servir? 00:03:45
pues nos pueden servir para copiar 00:03:48
un fichero en otro, por ejemplo, para eso sí 00:03:49
porque cuando yo quiero copiar un fichero en otro 00:03:51
desde una aplicación Java 00:03:53
lo que contiene 00:03:55
la información, lo que significa, el significado 00:03:57
me da igual, lo único que quiero 00:03:59
es llevar estos bits aquí 00:04:01
lo único que quiero es eso, el significado me da igual 00:04:02
pues si el significado me da igual 00:04:05
con estas clases tengo suficiente 00:04:07
porque lo que haré será 00:04:09
llevar a la aplicación java 00:04:10
y luego de la aplicación java llevar al otro 00:04:13
¿vale? entonces 00:04:14
en aplicaciones java 00:04:16
que necesiten trasladar esos bits 00:04:18
o hacer cosas con esos bits 00:04:21
pero sin importarles 00:04:23
en absoluto lo que representan 00:04:25
pues estas clases pueden ser suficientes 00:04:27
¿vale? vamos a hacer ese ejemplo 00:04:29
sin más, un ejemplito de una aplicación 00:04:31
java para copiar un fichero 00:04:33
en otro, por ejemplo, con otro 00:04:35
nombre y ya está 00:04:37
y luego ya pasamos a clases 00:04:38
que ya están montadas sobre 00:04:41
estas que hacen cosas un poquito más 00:04:43
sofisticadas, ¿vale? pero están 00:04:45
montadas sobre estas que son la base 00:04:47
las de mover bits de un lado a otro 00:04:49
venga, pues vamos a 00:04:51
hacernos aquí en el proyecto 00:04:53
ejemplo que estábamos 00:04:55
otro paquete 00:04:56
que lo vamos a llamar 00:04:58
modo byte 00:05:02
para que 00:05:03
sepamos que ahí está el ejemplito 00:05:04
para hacer esta aplicación Java 00:05:10
que usa estas clases que hemos dicho 00:05:11
para copiar un fichero en otro 00:05:13
pues venga 00:05:14
nos hacemos una clase cualquiera 00:05:16
que va a tener ya el main 00:05:19
copiar ficheros 00:05:20
vale 00:05:26
venga pues en esta clase vamos a hacer un método 00:05:27
que va a servir 00:05:34
para 00:05:36
he dado un nombre de fichero 00:05:40
origen y un nombre de fichero destino 00:05:42
copiar el fichero origen en el fichero destino 00:05:44
como si hiciéramos un move del sistema operativo 00:05:47
desde la línea de comandos 00:05:49
pues venga 00:05:52
vale, pues este método vamos a hacer 00:05:54
le vamos a pasar los nombres 00:06:01
directamente es como si simularamos el 00:06:02
el copy 00:06:05
del move o como lo queréis llamar 00:06:06
del sistema operativo 00:06:09
que recibe le ponemos dos nombres 00:06:10
le ponemos ahí dos cadenas 00:06:11
pues entonces 00:06:13
vale 00:06:15
Fichero origen 00:06:19
Y el otro 00:06:23
Fichero destino 00:06:26
Ala 00:06:32
Bueno, pues entonces 00:06:35
Aquí uno ve este método y dice 00:06:37
¿Qué tengo que hacer con esto? 00:06:39
Este fichero tiene unos bits 00:06:41
Y este tiene otros 00:06:42
El objetivo es que estos bits se muevan aquí 00:06:44
¿Tengo que interpretar algo sobre su contenido? 00:06:47
No tengo que interpretar nada 00:06:51
Solo tengo que moverlos de un sitio a otro 00:06:52
No tengo que interpretar nada 00:06:53
pues entonces estas clases 00:06:55
input, file, input, string, file, output 00:06:57
nos valen, porque estas clases valen 00:06:59
para mover, nada más 00:07:01
para trasladar, pues estas me valen 00:07:03
que son las más básicas, las más sencillas 00:07:05
las que menos carga computacional tienen 00:07:07
vale, pues entonces 00:07:09
una aplicación java 00:07:11
para acceder a ficheros 00:07:12
ya sabemos que puede hacer 00:07:15
dos cosas, o leer 00:07:17
y leer es 00:07:19
coger del fichero y llevarlo a variables internas 00:07:20
para con esa 00:07:23
una vez que ya están variables internas 00:07:25
hacer con eso lo que sea 00:07:27
o escribir que es lo que tienen variables internas 00:07:27
llevarlo a un fichero 00:07:31
esas son las dos cosas 00:07:32
que se pueden hacer con ficheros 00:07:35
desde una aplicación Java 00:07:36
coger su información 00:07:38
y traerla a variables 00:07:40
de la aplicación 00:07:43
o contenido que está en variables 00:07:44
moverlo a ficheros 00:07:47
esas son las dos cosas que se puede hacer 00:07:48
y luego ya con esa información 00:07:50
que está en variables uno ya procesa 00:07:52
hace todo lo que necesite hacer 00:07:54
porque 00:07:56
de nuevo repito, una aplicación Java 00:07:58
cuando opera con datos 00:08:00
esos datos tienen que estar en variables 00:08:02
ahí sí que no hay tutía, tienen que estar en variables 00:08:04
me da igual qué tipo de variables 00:08:06
primitivas, colecciones, objetos, pero una aplicación 00:08:08
Java solo puede trabajar con los datos 00:08:10
que están en sus variables 00:08:12
¿de dónde han llegado 00:08:13
esos datos? ¿que me los han metido en la 00:08:16
consola? ¿que los he leído de un fichero? 00:08:18
bueno, pues ya veremos, depende 00:08:20
pero una aplicación solo puede operar 00:08:22
con lo que tienen sus variables 00:08:24
y como cuando la aplicación termina 00:08:25
lo que está en las variables 00:08:28
se borra porque las variables 00:08:30
desaparecen, pues por eso 00:08:32
uno se tiene que preocupar si quiere 00:08:34
que esa información se conserve de llevarla 00:08:36
a un fichero antes de que la aplicación 00:08:38
termine o lo que sea 00:08:40
bueno, pues entonces aquí nuestra operación 00:08:41
es estos bits que están en este fichero 00:08:44
tienen que ir a estos bits que están en este 00:08:46
como lo único que puede hacer Java es 00:08:47
llevar de 00:08:50
fichero a variable 00:08:52
o de variables a fichero, pues tendremos que hacer 00:08:54
esos dos pasos, primero llevamos 00:08:56
de este fichero a variables 00:08:59
y luego llevamos de variables 00:09:01
a este fichero, esos dos pasos hay que hacerlos 00:09:02
porque no se puede llevar de un fichero 00:09:04
a otro directamente, siempre hay que pasar 00:09:07
por RAM, vale 00:09:08
el disco duro no se puede 00:09:10
comunicar entre sí directamente, de un sector 00:09:12
a otro, es imposible, siempre tiene que viajar 00:09:14
a la memoria RAM y salir otra vez 00:09:16
vale, pues aquí 00:09:19
igual, yo tengo dos ficheros 00:09:21
uno tiene que viajar a las variables de mi aplicación 00:09:23
a la RAM y de ahí irse a el otro fichero 00:09:26
vale, pues entonces vamos a hacer primero la operación de lectura 00:09:30
la de lectura es, voy a leer de uno y luego voy a escribir en otro 00:09:33
bueno, pues leer bytes de un fichero, el file input string 00:09:38
pues nada, lo instanciamos aquí, y como se instancia 00:09:42
este objeto file input string, pues como el file reader 00:09:50
le damos 00:09:53
o bien el nombre 00:09:55
del fichero directamente 00:09:58
o el objeto file asociado 00:09:59
el constructor me permite las dos variantes 00:10:01
igual que file reader 00:10:03
como tenemos el nombre 00:10:04
vamos a usar el constructor 00:10:06
que recibe el nombre 00:10:08
el string con la cadena de texto que es el nombre 00:10:10
vale, pues ya tenemos un 00:10:13
flujo conectado a un fichero 00:10:19
con este nombre, hay preparado 00:10:21
para hacer operaciones de lectura 00:10:23
es decir, para hacer operaciones 00:10:24
de coger del fichero y llevar 00:10:27
a la memoria RAM 00:10:29
a variables 00:10:31
esto habrá que importarlo, claro, del paquete 00:10:31
java.io 00:10:35
y de nuevo, esta operación 00:10:35
puede lanzar una excepción 00:10:39
file not found exception 00:10:40
y te dice, tienes que capturarla 00:10:42
o avisar, para quien use este método 00:10:45
pues por no complicar el código 00:10:47
la propagamos 00:10:49
throws, ala, ya está 00:10:50
y ahora toca leer 00:10:53
bueno, pues esto es el mismo bucle de lectura 00:10:54
el mismo que con el FileReader 00:10:57
cada lectura, este tiene un método read 00:10:59
igual que tenía el FileReader 00:11:03
este método 00:11:05
este método que te hace, te lee un byte 00:11:07
silencio 00:11:09
con leerte un byte 00:11:11
me refiero, coge un byte del fichero 00:11:13
y te lo lleva 00:11:15
a una variable 00:11:17
del programa 00:11:18
¿a qué tipo de variable? a una variable de tipo byte 00:11:20
podría ser porque cabe 00:11:23
en una variable de tipo byte, pero no 00:11:25
te lo lleva a una variable 00:11:27
de tipo int 00:11:29
ahí te lo lleva 00:11:30
entonces, esto que hemos hecho aquí 00:11:32
bueno, aparte de que puede hacer una excepción 00:11:35
y o exception que vamos a propagar 00:11:37
esta sentencia de aquí 00:11:39
te lee un único byte 00:11:42
del fichero, lo coloca 00:11:45
en el byte menos 00:11:47
significativo de la variable n 00:11:49
que ya sabéis que tiene 4 00:11:50
en el byte menos significativo 00:11:52
lo coloca, el resto lo deja a ceros 00:11:55
y el posicionador interno 00:11:56
del fichero lo avanza para que 00:11:59
en la siguiente lectura, en el siguiente read 00:12:00
leamos el siguiente, exactamente igual que con 00:12:02
el file reader 00:12:04
en realidad 00:12:07
la única diferencia es que con el file reader 00:12:07
si luego hacíamos el casting a char 00:12:10
pues nos daba un carácter, aquí no 00:12:12
nos da nada, porque lo mueve tal cual 00:12:14
es que no hace ninguna 00:12:17
los bits tal cual son, nos lleva a n 00:12:18
Vale, pues entonces 00:12:21
¿Y qué queremos hacer con cada uno de ellos? 00:12:24
Llevarlos al otro 00:12:27
Mismo bucle de lectura que en el file reader 00:12:28
Tendremos que hacer tantos read de estos 00:12:32
Tantos read como bytes haya 00:12:35
Esto habrá que meterlo en un while, ¿verdad? 00:12:37
Entonces el bucle de lectura se queda igual que el file reader 00:12:41
Mientras 00:12:43
Yo aquí declararía mi variable n 00:12:46
Y mientras n, siendo n el resultado de hacer una lectura, sea diferente de menos 1, porque tenemos la misma forma de avisar que con el file reader. 00:12:49
La sentencia esta read, coge un byte y lo lleva a n, a la parte menos significativa, el resto lo pone todo a ceros. 00:13:16
vale, que ocurre 00:13:24
si este react intenta leer 00:13:27
la marca fin de archivo 00:13:29
porque ya acabamos, intenta leer la marca 00:13:31
fin de archivo 00:13:32
en este numerito n 00:13:34
lo que coloca es el número entero 00:13:36
menos uno, entonces como el número entero 00:13:38
es menos uno, es negativo 00:13:41
y por tanto su bit de signo es uno 00:13:42
luego no, es la forma 00:13:44
de ver que ese no es un byte 00:13:47
del fichero, porque si fuera un byte del fichero 00:13:49
este numerito n tendría todos ceros aquí 00:13:50
con lo cual es imposible que sea menos uno 00:13:53
porque su bit de signo es cero, es positivo 00:13:55
entonces si esto hubiera 00:13:57
hecho una lectura 00:13:59
válida, una lectura válida 00:14:01
jamás podría ser menos uno 00:14:03
jamás podría ser menos uno, podría ser lo que fuera 00:14:05
pero no menos uno porque el bit de signo sería 00:14:07
cero, luego sería un positivo 00:14:09
si me devuelve menos uno 00:14:11
es porque lo que ha leído 00:14:14
es la marca fin de archivo, entonces lo ha colocado 00:14:16
todo a unos 00:14:17
y entonces es mi manera de ver 00:14:18
que, ah, vale, vale 00:14:21
no has conseguido mover un byte 00:14:22
no lo has conseguido, pues si hubieras conseguido 00:14:25
n tendría un número positivo 00:14:27
el que fuera, pero positivo 00:14:29
no lo has conseguido, me estás avisando 00:14:31
poniendo menos uno en ese n 00:14:33
pues ya está, esta es la misma 00:14:35
condición de fin de archivo en el file real 00:14:37
pues mientras n, siendo n 00:14:39
el intento de leer 00:14:41
el byte, no me haya 00:14:43
devuelto este resultado 00:14:45
mientras no me lo haya devuelto, yo ya con n 00:14:47
hago ahí lo que quiera, n es un byte 00:14:49
que tiene bits, que a saberlo decodifica eso 00:14:51
ni idea, un char no 00:14:53
no tiene por qué, ni idea 00:14:55
vale, en este ejemplo en concreto, ¿qué queremos hacer 00:14:57
con sn? queremos mandarlo al otro 00:14:59
archivo, y así, leemos byte 00:15:01
escribimos, leemos byte, escribimos, leemos byte 00:15:03
escribimos, el otro archivo está 00:15:06
sin abrir, pues vamos a 00:15:07
abrirlo, este, como este caso es 00:15:09
para escribir 00:15:11
pues vamos a 00:15:12
abrirlo con file output 00:15:15
stream 00:15:17
que es para escribir bytes 00:15:20
de nuevo el constructor 00:15:22
o bien se le pasa 00:15:30
la cadena de texto que tiene el nombre 00:15:32
o el objeto file asociado 00:15:34
da igual, admite ambas opciones 00:15:36
como tenemos la cadena de texto 00:15:38
en lugar de hacer new file esa cadena 00:15:39
pues le pasamos el nombrecito 00:15:41
y ya está, fichero 00:15:44
destino 00:15:47
y este admite un segundo 00:15:49
parámetro que tiene la misma 00:15:55
utilidad que en el file writer 00:15:57
que es, cuando yo abro este fichero 00:15:59
puede ocurrir dos cosas 00:16:01
que este ya exista 00:16:03
de antes o que no exista 00:16:05
si no existe de antes 00:16:07
se crea nuevo y limpio 00:16:09
pero y si existe de antes 00:16:10
¿qué hace? pues si existe de antes 00:16:13
lo abro para escribir pero tengo dos opciones 00:16:15
me posiciono al final para añadir 00:16:17
o me posiciono al principio 00:16:20
y todo lo que hay después 00:16:22
lo tiro a la basura 00:16:23
¿cuál de las dos opciones escoge? 00:16:24
depende de si yo aquí pongo true o false 00:16:27
si pongo true 00:16:29
se posiciona al final 00:16:31
para añadir a continuación 00:16:33
de lo que ya hubiera, exactamente igual que 00:16:35
en el file writer, igual, si pongo 00:16:37
false, no añade, se posiciona 00:16:39
al principio, elimina lo demás 00:16:41
si no ponemos nada 00:16:42
la opción por defecto es como haber puesto false 00:16:44
todo esto es igual que el file writer 00:16:46
en nuestro caso, vamos a copiar 00:16:48
este en este otro 00:16:51
si el fichero existe, pues lo vamos a sobrescribir 00:16:52
podríamos, si queremos hacer 00:16:55
este método más bonito, por ejemplo 00:16:59
podríamos hacer aquí, vamos a ver si existe 00:17:01
y si existe avisamos 00:17:03
desea sobre escribir 00:17:05
¿cómo podríamos ver si este archivo existe? 00:17:06
pues para esto tenemos la clase file 00:17:10
que me permite obtener información sobre el archivo 00:17:11
si existe, si es de lectura, escritura 00:17:13
pues podríamos instanciar un objeto 00:17:15
file asociado 00:17:17
a ese archivo 00:17:19
a este 00:17:22
fichero destino 00:17:26
y ahora podríamos hacer 00:17:29
Si el fichero existe, le preguntamos 00:17:33
¿Desea sobrescribir sí o no? 00:17:37
Y si te dice que no desea sobrescribir, retún 00:17:38
Ya está, que no haga nada 00:17:41
Podemos hacer eso, ¿no? 00:17:42
Si f.existe 00:17:45
Si el fichero existe, este fichero 00:17:49
Pues le podríamos preguntar ahora ya sí 00:17:52
El fichero existe 00:17:55
¿Desea sobrescribir? 00:18:05
leemos 00:18:15
su respuesta 00:18:16
si no 00:18:18
para lo cual pues hay que leer del teclado 00:18:19
con escáner o con lo que 00:18:28
os dé la gana 00:18:30
aquí ya la tengo ahí 00:18:31
vale 00:18:42
yo leo con 00:18:42
esta clase 00:18:44
y yo haría ya directamente 00:18:46
si teclado.leercadena 00:18:52
igual a no, no desea sobrescribir 00:18:57
es igual 00:19:00
a n 00:19:03
pues entonces, como me ha dicho 00:19:04
que no, ya no tengo más que 00:19:12
hacer el método que termine 00:19:14
por ejemplo, pues que termine 00:19:15
entonces aquí ya le puedo poner directamente 00:19:17
return 00:19:21
y listo, vale 00:19:23
entonces si el fichero existe 00:19:25
me avisa y me dice 00:19:27
¿quiere sobreescribir? le digo que no 00:19:29
vale, pues termina 00:19:31
¿que no le he dicho que no? 00:19:32
No entraría aquí, el método sigue y ahora ya hace todo esto. 00:19:35
De hecho, esto lo voy a poner para que lo haga aquí solo si lo necesita. 00:19:38
Bueno, pues nada. 00:19:49
Hemos dicho que o bien no existe, con lo cual no ha entrado en este if, 00:19:52
o bien no existe, o bien existía, pero ha dicho que sobrescribe. 00:19:57
En cualquiera de esas dos cosas, si no existe o si existiendo quiere sobrescribir, 00:20:00
en cualquiera de ellas hemos llegado a este punto. 00:20:04
hemos llegado a ese punto, vale, pues abrimos esto para leer, que es lo que estábamos, abrimos esto para escribir, vale, no le ponemos que añada, porque nos ha dicho que sobrescribe, pues así se queda, importamos de aquí, y nos dice la excepción, espérate, algo, he escrito algo mal, porque, ah, no, no, vale, vale, y ahora ya, 00:20:07
voy leyendo del primero 00:20:39
con cada byte leído, ¿qué quiero hacer? 00:20:41
llevarlo al otro, y se acabó 00:20:43
y para eso tendré 00:20:45
un método GRUITE al que le paso 00:20:46
ese byte 00:20:49
y ya está 00:20:51
¿y el GRUITE qué hace? 00:20:52
el GRUITE coge el byte 00:20:55
menos significativo de este 00:20:57
el menos significativo 00:20:59
porque en ese es en el que está la información 00:21:01
el resto están solo 00:21:02
para habilitar esa posibilidad de poner el menos uno 00:21:04
solo están para eso 00:21:07
pero no tienen información 00:21:08
la única información está en el byte 00:21:10
menos significativo de n 00:21:13
vale, pues este lo que hace es eso 00:21:14
coge el byte 00:21:18
menos significativo de n 00:21:20
que es donde se guardó lo que leyó 00:21:22
y va al otro 00:21:24
y se acabó, cuando este bucle ha terminado 00:21:24
pues ya podemos cerrar los dos 00:21:28
y listo 00:21:30
bueno, pues con este 00:21:37
ejemplito sencillo en el cual 00:21:38
lo único que necesitamos es coger los bytes 00:21:40
Llevarlos a sitios, pero lo que codifiquen nos da igual 00:21:42
Pues con estas dos clases que son de muy bajo nivel 00:21:45
Y por tanto muy eficientes computacionalmente 00:21:49
Pues nos vale 00:21:51
Si vamos a probarlo ahora 00:21:52
Desde aquí 00:21:59
Fichero origen 00:22:02
Y aquí 00:22:06
Fichero origen 00:22:14
Le voy a pedir el destino 00:22:20
Luego llamo al método 00:22:22
Fichero destino 00:22:23
Y ahora voy a llamar al método 00:22:30
Copiar fichero 00:22:33
Este que le he dicho 00:22:34
Copialo aquí 00:22:39
Y vamos a ver si funciona y lo copia 00:22:40
Como lanza excepción, pues me dice 00:22:44
Si tienes que hacer algo, pues throws 00:22:46
El throws se va aquí al main 00:22:48
Y ya está 00:22:49
Vale, entonces estoy en este fichero 00:22:51
Uy, en este proyecto 00:22:55
Vamos a probar 00:22:57
Este de aquí, destino 00:22:58
Vamos a copiarlo en destino2 00:23:02
Pues venga, ejecutamos esto 00:23:04
Fichero origen, este 00:23:10
Copialo en destino 2 00:23:15
No dice nada, suponemos que lo habrá copiado 00:23:18
Vamos a actualizar 00:23:22
Refresh ahí 00:23:25
Y destino 2 está aquí, que efectivamente tiene la misma información 00:23:29
Si dijéramos que copie destino en intercala 00:23:34
Que ya existe, es cuando me dirá lo de 00:23:37
¿Quieres sobreescribir patatín patatán? 00:23:40
vamos a probarlo 00:23:42
queremos copiar destino en 00:23:44
le voy a volver a decir destino2 00:23:47
que ya existe 00:23:49
¿desea sobreescribirlo? pues si le digo que no 00:23:49
pues ya está, ha terminado y no lo ha sobreescrito 00:23:54
y si le digo que sí, pues lo habría sobreescrito 00:23:56
aunque en este caso tendrían lo mismo ya 00:23:58
pero bueno, pues nada 00:24:00
queda ahí ese ejemplo 00:24:04
para ilustrar estas dos clases 00:24:05
que son las más básicas 00:24:08
de ese paquete 00:24:10
que mueven bytes 00:24:12
con este read que hemos visto y con el write 00:24:13
luego tiene nombre más métodos para hacer más cosillas 00:24:16
y eso, pero bueno 00:24:18
bueno, pues entonces 00:24:19
quedémonos por ahora con estas cinco clases 00:24:26
la clase file 00:24:28
reader, writer, input string, output string 00:24:30
con los ejemplos de uso que hemos visto 00:24:32
para que sirven, como las podemos 00:24:34
usar para algunas cosas básicas 00:24:36
y ahora ya vamos a saltar 00:24:38
a otras clases que nos pueden ser más útiles 00:24:40
bueno, pues estas otras 00:24:43
clases que vamos a ver tienen que ver con 00:24:47
esto de aquí, serialización 00:24:49
de objetos 00:24:52
tiene que ver 00:24:54
con este concepto 00:24:56
vale, pues nosotros en nuestra aplicación 00:25:01
en nuestras aplicaciones normalmente 00:25:03
las variables pueden estar 00:25:05
en variables primitivas, en numeritos enteros 00:25:07
en char, en string 00:25:10
pero muchísimas veces están 00:25:11
la mayoría de veces están en objetos 00:25:13
objeto alumno, objeto cliente 00:25:14
en nuestras aplicaciones 00:25:17
tienen de repente un montón de objetos alumno 00:25:18
y la aplicación se cierra 00:25:21
o se tiene que reiniciar 00:25:24
y todos los alumnos que se han dado de alta 00:25:25
se van a perder para que luego cuando la aplicación termine 00:25:27
tenga yo que meterlas de nuevo 00:25:30
hombre pues no, lo ideal es que todo eso 00:25:31
que tenemos en nuestras colecciones 00:25:34
en nuestros maps, en todo eso 00:25:36
pueda ir fácilmente a algún sitio 00:25:37
para que cuando la aplicación 00:25:40
se arranca o se reinicia pues automáticamente 00:25:42
vuelva otra vez 00:25:44
es el funcionamiento ideal, que no tengamos 00:25:45
que cada vez que arranca una aplicación meterle 00:25:48
todos los datos. Si los datos 00:25:50
son 30.000 usuarios, ¿los tenemos que meter 00:25:52
cada vez? Pues no. 00:25:54
Entonces, todo ese conjunto 00:25:56
de datos que está en colecciones 00:25:58
de objetos enormes, todo ese conjunto 00:26:00
de datos, su sitio 00:26:02
natural de alojarse, obviamente 00:26:04
es una base de datos. 00:26:05
Porque en una base de datos, además, 00:26:08
podemos guardar algo tan importante 00:26:10
como la estructura. Es decir, 00:26:12
no solo el contenido, 00:26:14
sino también una información 00:26:16
sobre el contenido, la estructura. Es decir, 00:26:18
tablas, yo tengo un alumno 00:26:20
el alumno tiene NIF, nombre y nota 00:26:22
pues hombre, ¿dónde va a estar 00:26:23
mejor guardado que en una tabla 00:26:26
que tiene también tres campos? 00:26:28
NIF, nombre y nota, estupendo 00:26:30
la misma estructura que tengo en la clase 00:26:31
la misma la tengo en una tabla 00:26:34
lo que está en las tres propiedades 00:26:35
está en tres campos, o sea, el sitio natural 00:26:37
para guardar objetos son las tablas 00:26:39
de las bases de datos 00:26:42
porque la estructura de propiedades es la estructura 00:26:42
de campos, es lo mismo 00:26:46
pero ahora aquí nos vamos a ver 00:26:47
como guardar los objetos 00:26:50
en bases de datos 00:26:53
eso se englobaría todo bajo un único nombre 00:26:56
que es el nombre de persistencia 00:26:59
persistencia en el contexto nuestro de desarrollo 00:27:01
tiene un único significado 00:27:03
que es que los datos de mi aplicación 00:27:06
estén permanentemente conectados a un soporte permanente 00:27:08
de forma transparente para mí 00:27:12
yo trabajo con los objetos 00:27:14
y eso está ahí permanentemente conectado a una base de datos 00:27:17
y así me tengo que despreocupar, desalvar, recuperar, etc 00:27:19
eso es lo que se llama persistencia 00:27:22
y todo eso exige unos frengos, unas clases 00:27:24
que se encarguen de hacer todo eso 00:27:28
todo eso es un módulo del año que viene 00:27:30
nosotros ahora lo que vamos a hacer es 00:27:32
hombre, para mí es algo, no quiero nada tan sofisticado 00:27:35
yo tengo una aplicación con 30 alumnos 00:27:39
cuando me acuesto por la noche yo quiero dejar el ordenador apagado 00:27:41
y cuando lo arranco por la mañana quiero que mis 30 alumnos 00:27:45
o mis 30 clientes sigan ahí en la aplicación 00:27:48
para seguir operando con ellos, quiero eso 00:27:51
simplemente, bueno pues 00:27:53
en situaciones así, ni siquiera tenemos 00:27:55
por qué habilitar un sistema gestor de base 00:27:57
de datos y poner ahí la base de datos, tampoco 00:27:59
hace falta, yo en 00:28:01
un fichero, me llevo mis 00:28:03
objetos y luego ahí los recupero 00:28:05
pero como me los llevo, no son 00:28:07
texto, son propiedades de un 00:28:09
objeto, es algo más raro, no me los puedo llevar con 00:28:11
un file writer, un file writer solo admite caracteres 00:28:13
un objeto no es eso, no es una sucesión 00:28:15
de caracteres, ¿cómo me los llevo? 00:28:17
Bueno, pues para eso se habilitan 00:28:19
unas clases muy sencillas de usar 00:28:21
que hacen esto 00:28:23
que decimos de llevar todo ese mogollón 00:28:25
que hay dentro de un objeto, que hay de todo 00:28:27
un nombre, un nif, todo ese mogollón 00:28:29
llevarlo a un archivo 00:28:31
y se le llama serializar 00:28:32
porque todo ese mogollón de propiedades 00:28:34
nif, nombre, nota, patatín 00:28:37
como que se las pone en filitas 00:28:39
se hace ahí una filita de bits 00:28:41
y eso se le llama serializar 00:28:43
lo convierto yo en una filita de bits 00:28:45
y esa filita de bits va al fichero 00:28:47
ese fichero cuando se abra 00:28:48
no es que no se pueda abrir, ahí no se entiende nada 00:28:51
porque esos son unos bits 00:28:54
que serializan de una manera interna 00:28:55
todo eso que está ahí, es que ahí es imposible abrirlo 00:28:57
pero claro, para eso están 00:28:59
las clases que deserializan 00:29:01
yo ahora cojo ese fichero 00:29:04
y cojo esa filita de bits 00:29:05
y me la llevo a la aplicación Java 00:29:08
la aplicación Java ya sí que lo puede entender 00:29:09
¿vale? entonces la serialización 00:29:11
lleva un fichero, ese fichero ya no se entiende ni papa 00:29:13
y nadie lo podrá abrir, pero luego si 00:29:15
desde otra aplicación hago la deserialización 00:29:17
vuelve otra vez 00:29:20
al objeto, y ese objeto 00:29:21
yo puedo trabajar con él 00:29:23
bueno, pues esas clases 00:29:24
de serialización de objetos serían 00:29:28
para serializar 00:29:29
hacia el fichero, es decir 00:29:32
llevar de objetos a fichero 00:29:33
serían object 00:29:35
output stream 00:29:37
esto es lo que sería 00:29:40
para escribir, ¿verdad? 00:29:45
para escribir al archivo y para leer sería esta vale esto sería para serializar y esto para 00:29:47
de serializar si es que ese verbo existiera que no existe bueno pues vamos a ver cómo 00:30:10
podemos usarlas en una aplicación por ahí vale pues venga vamos a hacernos una aplicación 00:30:24
vale, vamos a ver 00:30:34
si pudiéramos coger aquí 00:30:42
una que tuviera entidades 00:30:44
main model, tiene alumno 00:30:48
y luego tiene aquí unas operaciones 00:30:50
que son 00:30:52
insertar, mostrar datos 00:30:53
de un alumno 00:30:56
alumno tiene 00:30:57
matrícula, lista de asignaturas 00:30:59
vale 00:31:04
pues vamos a echarle un vistazo a esta aplicación 00:31:06
de ejemplo alumnos que tenemos aquí 00:31:07
que es una con las que 00:31:09
hemos trabajado en su momento para ver colecciones 00:31:11
vale, esta aplicación 00:31:14
que tenía, tiene 00:31:16
la única entidad con la que trabajaba 00:31:17
el alumno 00:31:19
vale, pues el alumno 00:31:21
se caracterizaba por su número de matrícula 00:31:25
su nombre, su edad 00:31:27
y un conjunto, una lista de asignaturas 00:31:28
de las que está matriculado, se supone 00:31:31
solamente el nombre en string 00:31:33
solamente el nombre 00:31:35
por eso se caracteriza el alumno 00:31:36
vale, aquí tenía sus guides, sus sets, etc 00:31:39
Y luego esta aplicación tiene unas funcionalidades, unas cosas que se puede hacer con esos alumnos que teníamos recogidas en esta clase de operaciones. Teníamos recogidas unas funcionalidades. Este proyecto está en la aula virtual, imagino. 00:31:41
vale 00:32:00
teníamos recogidas unas funcionalidades que eran 00:32:02
los datos 00:32:04
estaban en una lista de alumnos 00:32:06
aquí estaban los datos 00:32:08
ahí están los datos 00:32:09
y ahora, ¿qué podíamos hacer con esos datos? 00:32:11
que estaban en esa lista 00:32:15
luego cuando la aplicación arranca 00:32:16
eso está limpio 00:32:18
cuando la aplicación arranca ahí no hay ningún alumno 00:32:20
eso está limpio 00:32:23
vale, pues ¿qué hacíamos aquí con esta 00:32:24
con estos alumnos? 00:32:27
Podíamos insertar un alumno. Vale, pues insertamos el alumno y ya está. Mostrar datos de un alumno dado su número de matrícula. Pues mostrábamos los datos, patatín. ¿Qué más cosas hacíamos? Matricular a un alumno de una asignatura. Pues esto hacíamos. 00:32:29
¿qué más hacíamos? desmatricular a un alumno 00:32:51
de una asignatura 00:32:54
le quitábamos el string 00:32:55
¿vale? 00:32:58
eliminar a un alumno 00:33:00
pues lo eliminábamos con el remove 00:33:01
¿vale? alumno que tenía 00:33:04
más asignaturas 00:33:06
pues nada, aquí hacíamos el máximo 00:33:07
para ver que alumno tenía más asignaturas 00:33:10
al alumno mayor, pues lo mismo 00:33:12
el número de alumnos 00:33:14
matriculados 00:33:16
pues 00:33:17
matriculados en una asignatura 00:33:19
en una, en esta 00:33:22
y luego a ver 00:33:24
si existe matrícula 00:33:26
este 00:33:28
si esta matrícula estaba 00:33:28
en el 00:33:32
en la lista 00:33:32
¿vale? por eso hacíamos 00:33:34
retune contains, bueno 00:33:38
pues este era un proyecto que usamos 00:33:39
en su momento para 00:33:41
practicar con listas y ya está 00:33:43
hacer remove, contains y poco más 00:33:46
pero claro, en este momento dijimos 00:33:48
a ver, los datos 00:33:50
de la aplicación 00:33:52
tienen que estar en memoria principal 00:33:53
porque no los podemos tener en ningún soporte 00:33:56
permanente porque no sabemos 00:33:58
cuando la aplicación arrancaba, esta lista 00:33:59
estaba vacía, y luego ya según 00:34:02
la aplicación iba llamando a insertar alumno 00:34:04
pues ya estaban apareciendo alumnos 00:34:06
y luego ya podíamos eliminarlos 00:34:08
de todo, cuando la aplicación 00:34:10
se cierra, pues no hay 00:34:12
ningún alumno, o sea, los alumnos 00:34:14
desaparecen y se acabó 00:34:16
Bueno, pues podríamos completar esta aplicación de tal manera que cuando la aplicación arranca, recoja los alumnos de un fichero de texto, si es que los hay, para partir ya con ellos y cuando la aplicación termine, que todos esos alumnos vayan a un fichero, por ejemplo. 00:34:17
Y así, si nosotros apagamos la aplicación, apagamos el ordenador, no pasa nada cuando la aplicación arranque de nuevas, pues los alumnos seguirán estando exactamente los mismos. 00:34:39
Entonces, como lo que tenemos que guardar son objetos, aquí no podemos hacer ni FileWriter ni nada, esto es un lío. 00:34:52
Entonces tenemos que usar estas clases de serialización. 00:35:01
Vale, pues por ejemplo 00:35:04
Vamos a hacernos un método 00:35:06
Se puede copiar un proyecto entero 00:35:07
Si, si haces copy paste 00:35:13
Copy luego paste 00:35:15
Te lo copia con 00:35:18
Pero si yo lo 00:35:19
Hice el otro día, si, a ver 00:35:20
Copias 00:35:23
Y ahora yo pongo aquí paste 00:35:26
Y me aparece aquí 00:35:28
Otro con, me pone el 2 pero lo puedes cambiar de nombre 00:35:29
Vale, pues venga 00:35:32
vale, pues vamos a añadir un método 00:35:35
que de nuevo 00:35:40
puede ser interesante en este proyecto 00:35:42
que es guardar datos en fichero 00:35:44
guardar datos y ya está 00:35:46
guardar datos 00:35:47
y lo que le vamos a pasar es el nombre 00:35:57
del fichero en el que 00:36:00
queremos que se guarde 00:36:02
bueno, pues cuando llamemos a este método 00:36:03
toda esa lista 00:36:15
va a ese fichero 00:36:17
y ahí se queda preparada por si alguien quiere 00:36:18
recuperarla en algún momento, toda esa lista 00:36:20
de objetos alumna 00:36:22
vale, pues entonces 00:36:23
ahora lo que queremos es 00:36:25
escribir 00:36:28
escribir, recordad que tenéis que asociarlo a 00:36:30
muevo de variables 00:36:32
a fichero 00:36:35
eso es escribir, operación de escritura 00:36:36
operación de salida 00:36:38
las clases que tengan output 00:36:40
en su nombre, object, output string 00:36:43
file output string 00:36:45
o las que tengan writer 00:36:46
las que tengan 00:36:47
writer o output son las que hacen 00:36:50
escritura, que es llevar 00:36:52
de variables a fichero 00:36:54
y las clases que tienen en su nombre 00:36:56
input o reader son las que 00:36:58
hacen lectura, que es de fichero 00:37:00
a variables, en este caso 00:37:03
queremos escritura 00:37:04
de variables, de la lista en este caso 00:37:06
al fichero, escritura 00:37:08
pues entonces es object output string 00:37:10
esta es la que nos 00:37:12
interesa, hemos identificado 00:37:14
que queremos serializar objetos 00:37:17
llevarlos al fichero 00:37:18
pues esta es la que nos interesa 00:37:20
porque esta es la que nos vale para guardar objetos 00:37:22
pues venga, la podemos instanciar 00:37:24
y ahora 00:37:27
la paso aquí debajo 00:37:29
para que se vea bien 00:37:30
pues nada, se instancia aquí con el 00:37:32
constructor que sabemos que metemos 00:37:34
dentro 00:37:40
pero claro, el constructor 00:37:40
¿qué necesita? 00:37:43
pues el objeto de amputación es una clase 00:37:45
más compleja, obviamente 00:37:47
porque lo que tiene que hacer es meterse en el objeto 00:37:48
empezar a romper las propiedades 00:37:51
patatín patatán 00:37:53
y en última instancia esta clase a quien acabará llamando 00:37:54
a quien acabará llamando por debajo 00:37:57
es a la file output string 00:37:59
que hemos mencionado antes 00:38:01
porque esa es la básica 00:38:02
file output string es la que te lleva bits 00:38:03
de variable a fichero 00:38:06
pues el object output string está montada 00:38:08
sobre la file output string 00:38:11
cogiendo las variables, desmenuzándolas 00:38:12
poniéndolas en fila, haciendo todo el desmadre que haga falta 00:38:15
y en última instancia ya llamara a FileOutputStream 00:38:17
para que FileOutputStream las lleve. 00:38:20
Bueno, pues entonces el constructor necesita 00:38:23
que le pasemos como parámetro 00:38:25
el nombre del FileOutputStream, 00:38:28
el objeto, perdón, el objeto FileOutputStream 00:38:31
sobre el que queremos montarlo. 00:38:34
¿Y sobre qué FileOutputStream queremos montarlo? 00:38:36
Pues sobre uno que esté asociado a este, obviamente. 00:38:39
Entonces aquí para ahorrarnos referencias, 00:38:42
pues directamente le podemos pasar esto. 00:38:44
file output stream y 00:38:46
num fichero 00:38:51
entonces le estamos diciendo 00:38:53
al object output stream que todo 00:38:56
eso que él va a desmenuzar ahí 00:38:58
luego lo mande 00:39:00
a través de este file output stream 00:39:02
que este ya es el que manda los bits 00:39:04
directamente, que lo mande 00:39:06
a través de este que a su vez está asociado 00:39:08
a este fichero, pues nada 00:39:10
tendremos que importar las clases 00:39:14
y propagar la excepción 00:39:16
correspondiente, bueno 00:39:22
pues el uso 00:39:32
de esto en realidad es inmediato 00:39:33
porque object.outputString 00:39:36
lo único que te hace es 00:39:38
le pasas un objeto y te lo manda 00:39:39
y ya está 00:39:41
tiene un método 00:39:42
se puede usar para más cosas 00:39:44
tú le pasas aquí un objeto 00:39:51
una referencia 00:39:54
y te lo serializa y te lo manda 00:39:55
¿que quieres mandar muchos? 00:39:58
pues tendrás que hacer un bucle para que te los mande todos 00:39:59
aquí queremos mandar todos los que están en la lista 00:40:01
pues entonces tendremos que 00:40:04
meter aquí un for 00:40:06
¿vale? para recorrer esta lista 00:40:08
que se llama 00:40:10
alumnos 00:40:14
¿vale? pues 00:40:16
para cada objeto 00:40:22
alumno, para cada referencia 00:40:24
que está en alumnos 00:40:26
A es una copia 00:40:28
de la referencia, pero como 00:40:30
la copia de dirección de memoria va al mismo lado 00:40:31
bueno, no os olvidéis de que 00:40:34
el for each 00:40:36
es una copia de la referencia, pero 00:40:36
claro, apunta al mismo sitio 00:40:40
Pues que queremos hacer con este objeto 00:40:42
Ala, ya está 00:40:44
Pues ya está 00:40:45
Ya tenemos todos los objetos serializados 00:40:48
Un chorizo ahí de bits que ni idea 00:40:50
De como lo ha hecho, pero están ahí 00:40:52
Entonces una vez 00:40:54
Que uno ha terminado de guardarlos 00:40:56
Todos, pues 00:40:58
Lo cerraría ahí 00:41:00
Vale 00:41:03
Entonces vamos a probar desde nuestro main 00:41:05
Que tendremos aquí uno de pruebas 00:41:12
En el proyecto teníamos un main 00:41:13
00:41:17
ejemplo alumnos 00:41:18
que estaba 00:41:23
aquí 00:41:25
vale, pues en este teníamos un main 00:41:31
para hacer pruebas 00:41:35
teníamos un insertar alumno, vamos a 00:41:36
dejarlo, va a insertar dos, este 00:41:39
y este 00:41:41
y luego teníamos aquí más pruebas 00:41:41
para comprobar que el alumno existía 00:41:44
matricular alumno 00:41:47
bueno, un montón de pruebas 00:41:49
de las funcionalidades que habíamos hecho 00:41:51
aquí más cositas 00:41:53
vale, vamos a dejar 00:41:57
nuestro main ahora mismo 00:42:01
con dos 00:42:02
que inserte a dos, para tener dos 00:42:06
y ahora 00:42:08
pues vamos a guardar los datos, entonces esto 00:42:10
claro, luego ya uno construye la aplicación 00:42:12
para guardar el momento que quiera 00:42:14
para si se ha dado la opción de salir 00:42:16
opción salir, quieres 00:42:18
pues este main tendría un 00:42:19
este main podría 00:42:22
tener un menú, ¿no? 00:42:24
un menú insertar alumno, no sé qué 00:42:26
y en la opción de salir 00:42:27
en la opción de salir, cuando el usuario de salir 00:42:29
pues en ese momento se llamaría guardar datos 00:42:31
en la de salir para que se queden guardados 00:42:34
pero bueno, como no tenemos 00:42:36
aquí el menú, vamos a insertarlos y a guardarlos 00:42:38
y la aplicación terminará 00:42:40
y ya está, habrá insertado a los alumnos y los guardará 00:42:42
pues venga 00:42:44
guardamos 00:42:46
datos, ¿en qué fichero? pues vamos a 00:42:48
pasarle un fichero de nombre 00:42:50
alumnos 00:42:51
guardar datos y esto como tiene 00:42:53
una excepción, pues me lo dice 00:42:58
No me lo dice porque entonces 00:42:59
Lo he debido poner mal 00:43:02
Ah, opera, ah, claro 00:43:03
Que no estoy en el mismo sitio, claro 00:43:05
Estoy en otra clase 00:43:07
Operaciones, vale 00:43:09
Y ahora ya sí que me dirá 00:43:12
Lo de la excepción 00:43:14
Ay, throws 00:43:15
Vale, pues vamos a parar aquí 00:43:19
Vale, un momentito 00:43:26
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
11
Fecha:
25 de mayo de 2024 - 17:58
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
43′ 31″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
177.54 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid