Saltar navegación

20250327 Persistencia Datos 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 27 de marzo de 2025 por Stefano C.

15 visualizaciones

Descargar la transcripción

Vale, estoy grabando, por lo tanto si habláis me autorizáis a grabar vuestra voz. 00:00:00
Vamos a empezar hoy el concepto, a ver, unas pinceladas de persistencia de datos. 00:00:07
En realidad la persistencia de datos se divide en dos grandes partes, digamos. 00:00:12
Una es trabajar con ficheros y la otra sería la gestión, el acceso a las bases de datos. 00:00:19
¿Vale? El acceso a la base de datos 00:00:27
Históricamente en esta asignatura 00:00:29
Es la que dejamos al final 00:00:31
Y si no nos da tiempo 00:00:33
No pasa nada porque en segundo 00:00:35
Tanto si hacéis DAM como si hacéis DAW 00:00:37
Seguramente vais a 00:00:39
Ver algo de acceso 00:00:41
A base de datos desde 00:00:43
Programación, por lo tanto no es una cosa 00:00:45
Que hagas algo de aquí y no lo he visto nunca 00:00:47
Además nosotros según 00:00:49
Esto no lo debería grabar 00:00:51
No lo grabo 00:00:56
Vale, entonces, dos grandes áreas, no me acuerdo si le había dicho o no, ¿vale? Después de esta pausa que quién sabe qué se ha dicho. Pues, uno son los ficheros, la otra es la base de datos. Sí, le había dicho, ¿vale? Entonces, empezamos con conceptos un poco genéricos, luego vamos a ver, empezar un poquito cómo se usa un fichero y cómo se guarda el fichero. 00:01:00
No es difícil, es bastante sencillo. 00:01:20
Ahora, algunas cosas se pueden complicar, hay algunos peligros y problemas que surgen por allí. 00:01:25
Tened en cuenta que nosotros llegaremos hasta un punto que será guardar objetos en un fichero, 00:01:34
para que luego cuando lo necesitemos lo podemos volver a pillar, y esto no es lo que se hace hoy en día. 00:01:41
Lo que vamos a aprender aquí es una base, es una idea básica que puede servir para mueblar nuestra cabeza, pero hoy en día nadie se soñaría en un proyecto serio de hacerlo como lo vamos a hacer nosotros. 00:01:47
Hoy en día hay plugin, hay herramientas, hay mecanismos más avanzados que aprenderéis el próximo año o en los años siguientes de gestión de la cosa. 00:02:05
Como por ejemplo, a lo mejor a alguien se os suena, Hibernate. Es una forma de gestionar la cosa. Tú tienes que configurar tu proyecto con varias cosas que no son triviales y una vez que lo has hecho, pues lo que haces es le dices a ellos, mira, guárdame estos ficheros y él lo guarda. 00:02:21
¿Vale? Pero hay que saber qué hacer. 00:02:41
¿Vale? Y entonces todavía es pronto. 00:02:43
Pero sí, que 00:02:45
lo que es guardar datos 00:02:46
en ficheros y luego sacar ficheros 00:02:48
de allí, pues sí que puede servir. 00:02:51
¿Vosotros no habéis visto, todavía me habéis dicho 00:02:52
XML? ¿Vale? 00:02:54
Pero, por ejemplo, lo que sí 00:02:57
el XML 00:02:58
es una cosa que 00:03:00
que hay gente 00:03:02
que la ama y hay gente que la odia. 00:03:05
¿Vale? Hay gente que dice la cosa peor 00:03:06
que ha pasado la informática. Hay gente que 00:03:08
dice no porque no se puede utilizar pero con lo que vemos ahora sí que se puede 00:03:10
trabajar con xml que queriendo creando xml o leyendo xml por ahora dejando 00:03:17
aquí aparcado lo veréis xml deberías empezar ahora porque tampoco queda 00:03:23
mucho tiempo no vais a ver xml vais a ver xml casi seguramente porque es una 00:03:27
parte importante de lenguaje de marcas o sea si habéis visto html pues igual html 00:03:37
solo que te inventas las etiquetas y ya está hemos dado xml pues ya está vale el código 00:03:43
programación orientado al objeto vale nosotros sabemos que es un objeto a este punto de nuestra 00:03:51
vida sabemos cómo definimos un objeto como definimos un objeto con una clase vale definiendo 00:03:58
una clase es una generalización de los objetos que luego voy a crear voy a definir los atributos los 00:04:09
métodos que pueden, o sea, los comportamientos de estos objetos 00:04:16
y por lo tanto para definir un objeto lo que se hace es definir 00:04:19
su generalización, su abstracción, ¿vale? que sería la clase 00:04:23
y luego a partir de ahí crea objetos concretos que podrán hacer 00:04:27
lo que he establecido en la cosa, ¿vale? El código que yo 00:04:31
escribo, compilado, etcétera, etcétera, se guarda normalmente 00:04:35
¿dónde? El código que yo escribo y que luego compilo 00:04:39
en Java, etcétera, etcétera, ¿dónde se guarda? 00:04:46
disco duro 00:04:51
¿vale? cosa interesante porque 00:04:52
tú cuando escribes tu programa 00:04:54
lo ejecutas 00:04:56
le haces el Java C 00:04:57
entonces obtienes el bytecode 00:05:00
¿vale? los puntos clases, cosas por el estilo 00:05:02
esos 00:05:04
ficheros, esa parte 00:05:05
ese código no se pierde 00:05:08
tú apagas el ordenador 00:05:10
lo enciendes otra vez y ese código 00:05:12
no se ha perdido 00:05:14
¿qué se pierde entonces entre apagar 00:05:15
y encender el ordenador otra vez. 00:05:18
Objetos y variables. 00:05:32
Esos sí son los que estamos perdiendo ahora mismo. 00:05:35
El código es el mismo, pero cada vez que lo enciendes 00:05:38
como si empezaras desde cero. 00:05:40
Si claramente en mi código hay una parte de inicialización 00:05:42
que me crea 300 alumnos en código, 00:05:46
que es una idea bastante fea, 00:05:49
pero si lo hace, cada vez que lo arrancare 00:05:51
me crearé estos 300 alumnos. 00:05:54
Pero los objetos que estoy creando 00:05:56
se están creando, ¿dónde? En la RAM. 00:05:59
En particular en una área de la RAM, que es un trozo de la RAM 00:06:03
que se dedica al proceso que yo estoy lanzando. Cuando yo ejecuto 00:06:07
la Java Virtual Machine, será un proceso que es el intérprete 00:06:12
y luego tendrá mi proceso, mi hilo de ejecución, que tendrá asociado 00:06:16
un trozo de memoria. ¿Vale? Entre procesos no se 00:06:20
comparte memoria. Entre threads sí. Es la diferencia que 00:06:23
entre procesos y threads, y si queréis saber más, en segundo de DAM. 00:06:27
Entonces, cuando yo creo objetos y variables, estos objetos y variables se guardan en RAM. 00:06:33
La RAM es la memoria principal, la memoria más rápida, más cara también, 00:06:40
pero tiene la cuestión de que si no tiene electricidad, todo lo que está en RAM se pierde. 00:06:45
Entonces, entre una ejecución y otra, o entre un encendido y otro del ordenador, 00:06:50
todo lo que estaba en la RAM, lo pierdo 00:06:56
¿vale? o sea que los datos 00:06:58
en RAM no persisten 00:07:00
para que persistan 00:07:01
tengo que utilizar el disco 00:07:03
duro, ahora vosotros sabéis 00:07:06
de sistemas informáticos que la RAM 00:07:07
va rápida y es bonita, pues el disco 00:07:10
duro es súper lento, cada vez que toco 00:07:12
el disco duro 00:07:14
ralentizo muchísimo 00:07:15
mi programa 00:07:17
de hecho, si vosotros tenéis 00:07:19
poca RAM en vuestro ordenador 00:07:22
y encendéis varios 00:07:23
programas, el navegador 00:07:25
luego un juego, luego no sé qué 00:07:28
llega un momento en que todo va súper lento 00:07:30
¿por qué va todo súper lento? 00:07:32
porque yo necesito trabajar 00:07:47
los programas trabajan con la RAM pero no hay suficiente 00:07:50
RAM para todos y entonces 00:07:52
los procesadores normalmente 00:07:54
hoy en día hacen lo que se llama programación 00:07:58
concurrente, o sea que 00:08:00
hay pocos recursos de procesamiento 00:08:02
un procesador con 00:08:04
cuatro núcleos 00:08:06
por ejemplo, pues eso quiere decir que puedo ejecutar cuatro hilos, cuatro hilos de ejecución 00:08:08
en cada momento. Ocho si tengo multitrading que hace cosas raras, pero me da igual. O 00:08:14
dieciséis si tengo un procesador más potente. Pero la cuestión es que eso son los que se 00:08:19
pueden ejecutar. Ahora, ¿qué pasa? El procesador los va cambiando constantemente, uno y otro, 00:08:23
uno y otro, dándome la ilusión que estén viendo todos a la vez. Pero en realidad, paralelismo 00:08:28
verdadero, pues solo lo puede hacer con muy pocos 00:08:34
procesos, con muy pocos threads, porque son los threads 00:08:37
que tengan los núcleos que puede ejecutar 00:08:40
¿vale? Ahora, si no tengo RAM suficiente 00:08:43
cada vez que un proceso llega al procesador 00:08:46
y tiene que ser ejecutado, quiere encontrarse los datos 00:08:49
en la RAM, pero si no hay espacio para todos 00:08:52
el sistema operativo empieza a hacer operaciones de swapping 00:08:55
o sea, pillo lo que está en la RAM 00:08:59
Libero una parte de la RAM de otro proceso 00:09:01
Que en este momento no se está ejecutando 00:09:05
Y lo copio en el disco duro 00:09:07
Voy a pillar lo que había copiado tuyo en el disco duro 00:09:08
Y lo copio en RAM 00:09:12
Y esto se está haciendo constantemente 00:09:13
Ahora como el disco duro es lento 00:09:15
Pues todo empieza a ir muy muy lento 00:09:18
Porque cada vez que hago esta operación de swapping 00:09:20
Pues esto es muy lentísimo 00:09:23
¿Sí? 00:09:25
Vale 00:09:27
Entonces, también el código que yo ejecuto se guarda en RAM 00:09:27
O sea, eso está guardado en el disco duro 00:09:34
Pero cuando ejecuto al principio el programa 00:09:37
Copio desde disco duro las instrucciones a RAM 00:09:40
Porque luego cuando se ejecuta RAM tiene que estar en RAM 00:09:44
Y luego todos los niveles de caché que vosotros conocéis 00:09:47
Siempre más cerca del procesador 00:09:51
Hasta llegar a la memoria más pequeña y más rápida 00:09:53
que son los registros del procesador 00:09:56
¿sí? 00:09:58
entonces, hemos dicho que nuestros 00:10:00
objetos en estas variables no persisten 00:10:02
se acaban, ¿vale? 00:10:04
los valores de atributos 00:10:07
de los objetos no persisten previamente en el disco 00:10:08
¿vale? cuando hago una new 00:10:10
se crea un nuevo 00:10:12
en un trozo de la rama, un nuevo objeto 00:10:14
y este trozo de la rama 00:10:16
se llama heap 00:10:18
mucio, ¿vale? 00:10:19
no, mucio es italiano, montón 00:10:22
es español, ¿sí? 00:10:24
los objetos se crean en esta zona 00:10:26
porque es una zona que funciona un poquito distinta 00:10:30
con como se crean en vez de las variables 00:10:33
que es otra zona que ahora vemos 00:10:35
y entonces no tiene el mismo funcionamiento que el otro 00:10:36
no sabría definiros bien 00:10:41
como funciona el heap de Java 00:10:45
sepáis simplemente que es otro tipo de 00:10:51
estructura datos dinámica 00:10:54
¿vale? no es 00:10:57
una cola, no es una pila 00:10:58
no es una lista 00:11:00
es otra forma de organizar 00:11:02
los datos allí, con muchas referencias 00:11:04
porque vosotros sabéis que los objetos tienen 00:11:06
toda esta cosa de referencias 00:11:08
etcétera, etcétera, ¿vale? 00:11:10
por otro lado, en vez de las variables locales 00:11:12
los parámetros, cuando llamo un método 00:11:14
y cosas por el estilo, se guardan en una zona 00:11:16
de memoria que se llama la stack 00:11:18
¿vale? que es esta pila 00:11:20
y vosotros sabéis que es una pila, ¿vale? 00:11:22
Entonces, cuando nosotros, ¿os acordáis el concepto que vimos al principio de curso de ámbito de una variable? El scope, ¿vale? Que una variable solo existe en el bloque en el que la declaro, ¿vale? Y muchas veces los bloques se relacionan también con métodos. 00:11:24
O sea, un método al fin y al cabo es un bloque. Yo llamo desde aquí y cosas por el estilo. Entonces existe esta pila que sustancialmente va apilando las nuevas llamadas de métodos o los nuevos bloques que se crean y allí en cada nivel de la pila crea las variables. 00:11:44
De esta forma que cuando se acaba un bloque, entonces todas las variables que estaban en ese nivel de la pila, se hace una pop en la pila, se quita la cabeza de la pila y todas esas variables ya no existen. 00:12:03
Es la razón de por qué existen las variables locales. 00:12:18
Tú dentro del bloque las declaras, declaras dentro de un for una int i, usas i todo lo que te da la gana dentro del for, pero cuando sale del for ya i no existe. 00:12:21
Si la necesito fuera de IMET, la tengo que guardar en algún lado o declararla fuera del FOR para que valga en el nivel más bajo de la pila. 00:12:31
¿Se entiende? 00:12:41
Vale. 00:12:43
Entonces, todo esto a nivel de RAM. 00:12:44
Cuando apago, enciendo o acabo la ejecución, se pierde todo. 00:12:46
¿Vale? 00:12:50
Cuando finaliza el programa, los datos de los atributos del IP y también algunos de los TAC, pues, no persisten. 00:12:51
¿Vale? 00:12:57
Aunque en muchos casos sería deseable. 00:12:58
¿Vale? 00:13:00
Lo que hemos hecho siempre, por ejemplo, con el alumno, pero puede ser con cliente, puede ser con coche, todo lo que yo he creado. Imaginaos las cosas que estáis haciendo ahora con Graphical User Interface, que ponéis los datos y los grabáis. Pues estáis creando cosas. No quiero que cada mañana que empiece a trabajar en mi empresa tenga que volver a grabar todos los datos de los clientes para poder trabajar con ellos. 00:13:01
entonces, no se existe 00:13:23
un mecanismo 00:13:26
automático de persistencia 00:13:28
en la mayoría de los lenguajes 00:13:30
de un reto de objetos, en particular 00:13:32
en Java, no existe algo 00:13:34
automático que dice 00:13:36
si ahora se va la luz, pues estaba 00:13:38
guardando todo en el disco duro y no he perdido 00:13:40
nada, lo tengo que hacer yo 00:13:42
manualmente, en el sentido, no 00:13:44
necesariamente soy yo el que va a escribir 00:13:46
ceros y unos con un 00:13:48
imán en el disco duro 00:13:50
¿Vale? Pero si soy yo que le tengo que decir en un determinado momento, este es el momento en el que tu programa, haz tu magia y guárdame estos datos que te paso en un fichero. 00:13:51
¿Sí? Si los guardo bien y lo hago bien, mañana cuando enciende mi ordenador, pues posiblemente siguen allí. 00:14:05
Si lo has escrito en formato texto, los puedo hasta mirar yo. Si lo he escrito de otro formato, puedo ir a mirar, pero veré estas cosas raras que hace alguna vez cuando abrís un fichero con el Notepad y hay carácteres que no son texto, ¿vale? 00:14:12
Entonces, dependiendo de allí, ahora lo veremos también, nosotros podremos escribir en fichero y decidir si escribimos bytes, entonces puede ser cualquier cosa, o si escribimos caracteres. 00:14:28
Entonces ya tengo algunas limitaciones porque estoy escribiendo caracteres y no cualquier cosa como un byte o cosa por el estilo. 00:14:42
Si estoy copiando y trabajando con ficheros de textos, utilizaré char y string y lo que sea, si los ficheros con los que estoy trabajando no están pensados para ser inteligibles, para ser humanos, entonces no son de tipo texto, pues debería trabajar con bytes. 00:14:48
porque si no, podría ser que un char no se corresponda exactamente a los bytes que estoy leyendo. 00:15:12
Y entonces podría ser que cuando voy a leer, yo leo en grupos para traducirlos en char, 00:15:21
y pues un grupo se queda en mitad porque allí acababa el byte o acababan los ficheros que estaba mirando. 00:15:26
Un ejemplo de ficheros que no utilizan cosas son los ejecutables. 00:15:32
Todos los ficheros que son .exe, si vosotros intentáis abrirlos con un bloc de notas, pues veis que no se entiende porque esos son ceros y unos que se interpretarán por el procesador. 00:15:37
Entonces, no son caracteres. Entonces, cuando lo voy a interpretar, el bloc de notas intenta interpretarlo como caracteres, salen cosas raras. 00:15:52
almacenamiento de datos 00:16:01
¿cómo conservamos valores de datos 00:16:05
en un dispositivo de almacenamiento 00:16:08
y cosas por el estilo? pues hay varias opciones 00:16:10
¿vale? opción número A 00:16:12
creando un archivo 00:16:14
¿vale? que es lo que veremos nosotros 00:16:16
entonces nosotros tenemos en nuestro oficiero 00:16:18
le guardamos los datos en modo 00:16:20
RAW, en modo crudo 00:16:22
en modo tal cual son 00:16:24
¿vale? lo guarda allí o en modo texto 00:16:26
¿vale? o en 00:16:28
Voy a copiar los ceros y unos 00:16:29
Que será este objeto 00:16:31
Al fin y al cabo todo en informática son ceros y unos 00:16:33
Entonces yo puedo 00:16:35
Trabajar con ceros y unos 00:16:37
Que sería el modo row 00:16:38
Y entonces mi objeto será una tira de ceros y unos 00:16:40
Pues copio estos ceros y unos en un fichero 00:16:43
Pues ya está, tengo mi objeto guardado 00:16:45
O si no, en modo texto 00:16:47
Veremos los dos ejemplos 00:16:50
También puedo tirar de la Java Virtual Machine 00:16:52
Y decir, Java Virtual Machine 00:16:56
Mira, yo te doy un fichero 00:16:57
Luego te doy un objeto, guárdamelo tú. Haz tu magia, haz lo que tienes que hacer. Yo no quiero saber cómo lo guardas, qué estás haciendo por debajo. Estoy abstraendo el cómo se hace, te estoy diciendo qué hacer. 00:16:59
Entonces, tengo este objeto, por favor guárdamelo tú, ¿vale? No todos los objetos se pueden guardar, hay características que tengo que tener en cuenta y cuidado porque la cosa se puede complicar, ¿vale? Esto se llama normalmente la serialización de un objeto, transformar un objeto en una serie de ceros y unos que pasaré al disco duro y que lo guardaré allí, ¿vale? 00:17:15
Veremos que para que un objeto sea guardado en un disco duro 00:17:40
Tiene que implementar la interfaz 00:17:44
Serializable 00:17:46
Serializable 00:17:48
No sé cómo se pronuncia 00:17:51
¿Vale? 00:17:52
Otra opción es 00:17:54
Molestar a las bases de datos 00:17:56
¿Vale? 00:17:59
Entonces decir a las bases de datos 00:18:00
Oye, mira, como son muchos datos los que tengo que gestionar 00:18:01
Y el disco duro no está optimizado para esto 00:18:04
voy a buscar a alguien que está especializado en guardar datos 00:18:07
y le digo, oye, mira, guárdame estas cosas, ¿vale? 00:18:11
A partir de allí se puede guardar de distintas formas, 00:18:14
como en unas tablas que tenga columnas distintas 00:18:17
y por cada columna tenga un atributo del objeto 00:18:22
y que yo guarde allí en cada columna su objeto, 00:18:25
o pueda utilizar un blob o lo que sea 00:18:28
para guardar enteros los objetos por ahí, ¿vale? 00:18:30
si necesito mucho esto 00:18:34
entonces tengo programas que necesitan guardar 00:18:38
y recuperar muchos de estos 00:18:41
objetos, pues posiblemente montaré 00:18:43
algunos de estos mecanismos como Evernate o cosas por el estilo 00:18:47
que me permite trabajar con 00:18:50
la base de datos y hacerlo rápidamente 00:18:53
nosotros por ahora no 00:18:55
vale, entonces empezamos a ver que nos hace falta 00:18:58
para poder trabajar con Java y hacer cosas con ficheros? 00:19:02
Pues la primera es la clase File, ¿vale? 00:19:07
Existe la clase File que ya existe en java.io, ¿vale? 00:19:10
Paquete de input-output, ¿vale? 00:19:14
Entonces es una clase que abstrae y representa un fichero. 00:19:17
Cuidado, no es un fichero, es un manejador de fichero, ¿se entiende? 00:19:24
Es como a nivel de Java 00:19:28
Puedo referenciar un fichero 00:19:31
Luego el fichero estará en el disco duro 00:19:35
Y será otra cosa 00:19:37
Pero si yo tengo que saber 00:19:38
Por ejemplo, preguntarme cosas como 00:19:40
Si este fichero ya existe 00:19:42
Si este fichero tiene dentro datos 00:19:44
O cosas por el estilo 00:19:47
Necesito un handler, un manejador 00:19:48
Desde la perspectiva de Java 00:19:51
Para poder decir 00:19:53
Este es un objeto que representa este fichero 00:19:54
ahora te hago preguntas a ti objeto y tú harás lo que sea para ir a mirar en el disco duro 00:19:56
si efectivamente estas cosas son verdaderas, son falsas, cuánto ocupas, etc. 00:20:02
El punto, es siempre lo que hacemos en Java al fin y al cabo, es intentar extraer cosas más o menos físico-reales. 00:20:08
Nosotros no queremos trabajar directamente con los discos duros y decirle 00:20:18
ponte a girar o ponte a buscar niveles de energía de donde has guardado en el SSD el fichero, 00:20:21
pues no me interesa, pues a mí me interesa extraer, decirle, oye, mira, esto es un fichero, vale, 00:20:28
ahora represento un fichero, usámoslo, ¿vale? 00:20:33
Para crear o abrir un fichero, en Java se invoca un constructor de la clase File, ¿vale? 00:20:36
Entonces yo creo un new file y ese de allí me crea ya el constructor. 00:20:41
Si quiero estar seguro que exista, está también una función de create file, si no existe, 00:20:44
Y existe un otro método que es el exists, que me devuelve true si el fichero ya existe y false si no, ¿vale? Entonces, una cosa estándar es crear el fichero como objeto, comprobar si ya existe, si ya existe lo utilizo, si no existe lo creo o lo relleno o doy un error, dependiendo de lo que quiero hacer, ¿vale? 00:20:50
Si estoy haciendo un programa donde está una serie de datos de inicialización, entonces tengo un fichero de init donde dentro pongo los datos iniciales de mi programa y este fichero no está, podría simplemente decir, oye, mira, tengo un problema, no existe el fichero init. 00:21:12
Si os acordáis, no nos ha pasado a nosotros un error cuando Manoli instaló la base de datos, nuestro programa Eclipse dejó de funcionar y que había que buscar un fichero .ini y cambiarle la cosa allí, que .ini de inicialización, porque allí no encontraba la Java Virtual Machine correcta. 00:21:30
¿No? ¿Sí? ¿Pasado este año? Pues yo creo que sí, pero no me acuerdo. Vale, entonces, una vez que tengo el fichero file, pues necesito trabajar con flujos de información, streams, ¿vale? Y tengo input stream y output stream. 00:22:02
Los output stream son los que escriben en el fichero, los input stream son los que leen de fichero. 00:22:21
La perspectiva es de mi programa, ¿vale? Entonces si yo estoy en mi programa, lo que es output es cosas que salen de mi programa y van fuera de mi programa, por ejemplo en un fichero. 00:22:31
Input son cosas que están fuera de mi programa y yo quiero leer para introducirlos en mi programa. 00:22:42
Entonces, cuando yo quiero salvar los datos, necesitaré un output stream para poder escribir los datos en memoria secundaria. Cuando enciendere mi programa otra vez y será un programa nuevo y quiere leer esos datos, necesitaré un input stream para poder leer desde ese lado. 00:22:48
¿Se entiende más o menos? El input stream es el más, y output stream son los niveles más bajos que podáis encontrar en Java. Si hurgáis, pues encontráis cosas más bajas, pero lo que usamos nosotros. 00:23:08
Es decir, que son los que están más cercanos a los ceros y unos, a los bytes que quiero leer. Por eso, las funciones que me proporciona InputStream y OutputStream son funciones de bajo nivel. 00:23:23
de escríbeme este byte en el fichero, léeme un byte, ¿vale? 00:23:41
Estamos trabajando con byte, no estamos trabajando con string, 00:23:47
no estamos trabajando con objetos. 00:23:49
Se lee byte por byte, se escribe byte por byte. 00:23:51
Y vosotros podéis hacer absolutamente todo a este nivel. 00:23:54
Ahora, ¿cómo es aburrido? 00:23:59
Porque, por ejemplo, si tú lees un entero, en vez de leer un entero, 00:24:01
deberías leer cuatro bytes y luego mezclar los estos bytes 00:24:05
y hacer un único entero grande 00:24:09
y a ese punto interpretarlo como un entero 00:24:11
si es un double son 8, si es un char 00:24:13
no lo sé, son 2, 1, cuánto es 00:24:15
pues sería complejo 00:24:17
pues hay 00:24:19
clases 00:24:21
que van subiendo el nivel 00:24:22
de abstracción que me crean 00:24:25
nuevos 00:24:27
métodos que se puedan 00:24:28
utilizar para sostancialmente 00:24:31
en vez de trabajar byte por byte 00:24:33
trabajar con cosas un poquito más 00:24:35
fáciles para los seres humanos 00:24:36
Entonces, InputStream encapsula un flujo de bits para leer, que pueden provenir del teclado, de un fichero, de una conexión de red, etc. El escáner probablemente por dentro tiene un InputStream o parecido, que lo que hace es leer la información que llega desde el teclado. 00:24:38
Pero para nosotros es una abstracción y nosotros no lo vemos. 00:25:01
No hemos creado InputStream, pero será. 00:25:04
La cosa interesante es que con InputStream tú lees desde cual sea la fonte que llegas. 00:25:07
Este año lo usamos para ficheros. 00:25:14
Si llegáis en segundo de DAM, pues lo usaremos para conexiones de red para los sockets. 00:25:16
Y es lo mismo. Es exactamente esta misma clase. 00:25:22
Tanto aquí como allá. 00:25:26
Es simplemente una clase que me permite leer bytes y guardarlos en una red de bytes. 00:25:27
Ahora, si no quiero trabajar con bytes, ¿por qué lo que estoy trabajando son mensajes de texto? 00:25:33
¿Por qué los ficheros que estoy utilizando son ficheros de texto? 00:25:42
¿Por qué no estoy trabajando con ficheros que no son inteligibles para los seres humanos? 00:25:45
y por lo tanto necesito que sean interpretados como carácteres, 00:25:56
en vez de utilizar un inputStream, podría utilizar un inputStreamReader. 00:26:00
Cuando está la palabra reader o writer, es que no estoy trabajando byte por byte, 00:26:07
sino que estoy trabajando con char, con carácteres. 00:26:14
Si tiene este reader, tiene esta funcionalidad extra. 00:26:17
Como yo asumo 00:26:22
Que ahora no estoy trabajando byte con byte 00:26:23
Pero asumo que estos sean caracteres 00:26:26
Puedo crear 00:26:28
Nuevos metodillos 00:26:30
Que ya asuman esto 00:26:31
Que ya digan, ah vale, cuando leo 00:26:34
No voy a leer un byte 00:26:36
Sé que voy a leer un char 00:26:37
Por lo tanto, la respuesta al read 00:26:39
No será que te devuelvo 00:26:42
Un array de byte 00:26:44
A lo mejor te devuelvo un array de char 00:26:45
¿Vale? Teniendo en cuenta que 00:26:47
De todas formas, un array stream reader 00:26:49
un inputStreamReader como veremos 00:26:52
como parámetro del 00:26:53
constructor pilla un inputStream 00:26:55
o sea que es sustancialmente 00:26:58
un involucrar 00:26:59
un rapear 00:27:02
no lo sé como decirlo 00:27:03
pillar algo que solo 00:27:06
tiene metodillos básicos de leer byte por 00:27:09
byte y decir vale te extendo 00:27:11
en un cierto sentido, no es una extensión 00:27:13
en términos de 00:27:15
herencia pero por ahí 00:27:17
voy a hacer cosas 00:27:19
más utilizando tus métodos porque 00:27:21
quien luego al final lee será siempre inputStream 00:27:23
pero ya me creo los métodos 00:27:26
que dice, leo los bytes suficientes 00:27:27
lo interpreto como char y por lo tanto 00:27:30
ahora trabajo con char, ese es un reader 00:27:32
¿vale? 00:27:33
y en particular tenemos el fileInputStream 00:27:35
y el fileReader que son 00:27:38
digamos, métodos 00:27:39
clases que permiten 00:27:42
trabajar con ficheros 00:27:44
¿vale? entonces nosotros 00:27:45
normalmente tendremos un fileInputStream 00:27:47
que tiene dentro un 00:27:50
inputStream como parámetro 00:27:51
Vosotros que ya habéis entendido 00:27:53
Cómo funciona la vida del programador 00:27:57
Como yo os estoy nombrando 00:27:59
Estas clases 00:28:01
Hoy por la tarde cuando os aburrís 00:28:03
Que no tenéis nada de mejor que hacer 00:28:05
Os abrís el API 00:28:07
Vais a mirar InputStream, InputStreamReader 00:28:08
Y veis la diferencia 00:28:11
Y veis que pueden hacer uno y otro 00:28:12
Para que luego a partir de mañana 00:28:15
Sepáis cuando usar uno 00:28:16
Y cuando usar el otro 00:28:19
Subiendo todavía a nivel más alto todavía, tenemos nuestro amigo el Buffered Reader. 00:28:22
El Buffered Reader es un reader, es parecido al otro, que añade la posibilidad de crear un buffer. 00:28:28
¿Qué es un buffer? Es una memoria temporal. 00:28:36
Es decir, que en vez de estar leyendo uno a uno los caracteres o los bytes o lo que sea, 00:28:38
yo puedo crearme una memoria temporal y guardar allí los caracteres. 00:28:45
Esto me permite crear métodos más útiles, más cómodos para nosotros los programadores 00:28:49
Como por ejemplo, puedo leer una línea entera de golpe 00:28:58
Mientras usando este de aquí, tengo que leer carácter por carácter 00:29:02
Esperando al carácter que sea retorno de carro, el barra n 00:29:07
Para decir, aquí se acaba la línea 00:29:12
pues usando la clase BufferedReader le puedo decir usar la operación ReadLine 00:29:14
que lee una línea entera y me la devuelve como un string, ¿vale? 00:29:20
Entonces si yo estoy guardando en mi fichero los datos línea por línea 00:29:24
pues utilizar un BufferedReader y leerlo línea por línea puede ser una opción, ¿vale? 00:29:33
Una de las formas que nosotros usaremos esto es que cada objeto que nosotros guardaremos 00:29:38
lo guardaremos en un formato textual, ¿vale? En una representación textual del objeto mismo y lo guardaremos un objeto por línea. 00:29:43
De esta forma, cuando luego voy a leer el fichero, lo que voy a hacer es leer de golpe una línea y allí ya tengo todos los datos del primer objeto. 00:29:53
Y ahora me lo voy parceando, me lo voy troceando, buscando cuál es el valor del primer atributo, el valor del segundo, para reconstruir el objeto. 00:30:02
es una de las formas que se puede hacer 00:30:11
y que veremos 00:30:13
vamos a leer un archivo de texto 00:30:15
¿vale? entonces se utiliza 00:30:18
una clase java.io 00:30:19
file reader y la java.io 00:30:21
buffered reader ¿vale? entonces 00:30:23
file reader fr es igual a 00:30:25
null, buffered reader br es igual a 00:30:27
null, pues esto se podría hacer directamente 00:30:30
aquí, pero me da igual 00:30:31
fr es igual a new file reader 00:30:33
de una ruta del archivo 00:30:36
¿vale? esta cosa de aquí crea 00:30:37
un nuevo file reader, que es un lector, entonces estamos hablando de char especializado en 00:30:39
ficheros, y aquí le pongo el nombre del fichero. Paréntesis sobre las rutas. Vosotros sabéis 00:30:46
que en el mundo de la informática hay dos tipos de rutas, las rutas absolutas y las 00:30:55
rutas relativas, ¿vale? ¿Dónde me espero que exista el fichero que voy a leer si no 00:31:01
le pongo ninguna ruta? Si aquí pongo mi fichero.txt, ¿dónde aparecerá ese fichero? No. Sí o 00:31:10
No, quién sabe. 00:31:24
En el Eclipse es el proyecto. 00:31:26
No source, no bin, el proyecto. 00:31:31
Esa es considerada la working directory. 00:31:36
Cuando yo busco un fichero sin decirle nada, lo busco allí. 00:31:39
Si esto es un proyecto, el proyecto, no, es el disco duro que tiene que empezar a girar. 00:31:44
Si yo tengo un proyecto, mi lista, qué sé yo 00:31:57
Aquí es donde se acerca el fichero 00:32:01
¿Vale? 00:32:04
No en source 00:32:06
No en bin 00:32:07
¿Vale? 00:32:09
Tened en cuenta que vosotros no lo pensáis 00:32:11
Pero vosotros editáis esto 00:32:13
Pero no ejecutáis esto 00:32:16
Ejecutáis siempre esto 00:32:18
Vosotros estáis ejecutando los .class 00:32:20
¿Vale? 00:32:23
El eclipse en automático 00:32:24
Cada vez que vosotros guardáis 00:32:26
Pilla vuestro punto Java 00:32:28
Le hace una compilación 00:32:30
Y guarda los puntos class 00:32:32
En esta carpeta de aquí 00:32:34
Tiene la misma estructura 00:32:35
Aquí está el paquete mi lista 00:32:37
Aquí tendrá el paquete mi lista también 00:32:39
Tiene la misma estructura del source 00:32:42
Pero no se ejecuta el source 00:32:45
Se ejecuta en el bin 00:32:46
Si este fichero de aquí 00:32:47
Le diera un 00:32:52
Si este class de aquí 00:32:53
leyera un fichero, me esperaría 00:32:56
que el fichero tuviera que estar aquí 00:32:58
¿vale? y si yo lo 00:33:00
lanzo con Java 00:33:02
directamente a esta clase 00:33:03
desde esta carpeta, posiblemente 00:33:06
debería estar aquí, ¿vale? 00:33:08
pero a nivel de Eclipse 00:33:09
Eclipse lo va a buscar aquí, esta es su 00:33:11
working directory, digamos que 00:33:14
el punto donde arranca 00:33:15
él piensa de estar en esta 00:33:17
directory de aquí, yo puedo crearme 00:33:19
aquí una carpeta que se llame ficheros 00:33:22
y poner ahí dentro los ficheros 00:33:24
O cosas por el estilo 00:33:25
Es un error enorme 00:33:26
Colosal 00:33:29
Y os suspendo instantáneamente 00:33:30
Si me ponéis algo así 00:33:32
No puedo hacerlo más grande 00:33:35
Porque luego se me bloquea la cosa 00:33:42
Como de dos puntos, barra, prog 00:33:44
24, 25, barra, mi lista 00:33:46
Es decir, una ruta 00:33:48
Absoluta 00:33:49
Las rutas absolutas no se usan 00:33:50
¿Por qué? 00:33:53
¿Sí? ¿Se entiende? 00:33:58
Es lo mismo que os pasa en HTML 00:34:00
cuando vosotros tenéis HTML o el CSS 00:34:02
si le ponéis la ruta relativa 00:34:05
y luego copiáis la carpeta en otro ordenador 00:34:08
os funciona perfectamente 00:34:11
si le habéis puesto la ruta absoluta 00:34:12
y lo lleváis a otro ordenador 00:34:14
que no tiene exactamente vuestra ruta 00:34:16
pues no va a funcionar 00:34:18
y esto os pasa muchas veces 00:34:19
porque vosotros trabajáis siempre solo en el mismo ordenador 00:34:21
luego lo subís al servidor 00:34:23
que este paso no lo estáis haciendo todavía 00:34:25
pero lo subís al servidor y no funciona nada 00:34:27
porque habéis puesto esta cosa aquí 00:34:29
es suspenso automático 00:34:31
Entonces, con esta de aquí me he creado un file reader 00:34:32
Dejad de hablar vosotros dos 00:34:40
Es 20 minutos, quiero reís de no sé qué 00:34:42
Sí, vosotros dos 00:34:45
Vale, entonces, con esto he creado el file reader 00:34:50
El file reader es esta cosa que me permitiría leer 00:34:53
¿Vale? Leer carácter por carácter es de un fichero 00:34:56
Es una clase de ese estilo 00:34:59
Pero yo quiero leerme una fila entera, una línea entera 00:35:00
Entonces, creo un BufferedReader, que es NewBufferedReader, y le paso como parámetro este FileReader. Aquí se podría pasar un file. A este punto, puedo hacer una cosa de este estilo. 00:35:04
mientras 00:35:21
br.redline 00:35:22
esta cosa de aquí es un 00:35:24
es leer una 00:35:26
fila, una línea 00:35:28
de texto, ¿vale? 00:35:30
esto me lo guardas dentro de línea 00:35:32
y mientras que esta línea 00:35:34
no sea null 00:35:36
es decir, que he leído algo 00:35:37
me he ido al fichero, he leído 00:35:39
y la respuesta que me ha dado no ha sido null 00:35:42
¿vale? pues 00:35:44
imprimo esa cosa 00:35:46
en pantalla 00:35:48
aquí habrá errores, cosas por el estilo, etc 00:35:49
finalmente cuando he acabado de leer todas las cosas 00:35:55
y cuando llegará un momento en que esto explote o acabe con un null 00:35:58
pues entonces lo que hago aquí es cerrar el file reader 00:36:02
esto en el 95% de nuestros ejercicios no sirverá 00:36:07
porque nosotros leemos y acabamos el programa 00:36:14
Son micro ejercicios. En términos de un proyecto más grande, yo debería estar pendiente de cuando un fichero se ha leído y no me hace falta más y que entonces lo pueda cerrar, pueda cerrar el canal de comunicación con ese fichero. 00:36:18
porque si se me olvida 00:36:35
y yo tengo que abrir un millón de ficheros 00:36:37
y estos millones de ficheros me ocupan 00:36:39
cada uno un trocito de espacio 00:36:41
en mi RAM, pues llega un momento 00:36:43
que tengo memory slicks en el sentido 00:36:45
de objetos que no me sirven 00:36:47
de nada, que se podrían quitar 00:36:49
pero no he quitado recursos 00:36:51
que se quedan allí ocupando espacio 00:36:53
porque en cada ejecución yo 00:36:55
creo un file reader y no lo 00:36:57
cierro y por lo tanto 00:36:59
él asume que antes o después 00:37:01
lo vas a reutilizar, entonces 00:37:03
se me queda ahí abierto, vale, entonces acostumbraos 00:37:05
a hacerlo, vale, si no, no, existe también 00:37:09
una versión del try catch que es el try con recursos en el que aquí 00:37:13
entre paréntesis declaráis unos 00:37:17
recursos que vais a utilizar aquí dentro, como por ejemplo estos dos 00:37:21
vale, y él en automático cuando acaba el block que trae 00:37:24
los destruye y hace un close de esa cosa aquí, vale 00:37:29
hoy en día se suele utilizar 00:37:33
no me interesa particularmente 00:37:35
pero lo veréis en códigos 00:37:37
y cuando luego programaréis 00:37:38
ahí afuera, posiblemente lo tendréis que utilizar 00:37:41
escritura de un archivo de texto 00:37:43
en vez de file reader uso file writer 00:37:48
en vez de baffered reader 00:37:51
uso print writer 00:37:53
print writer 00:37:55
a lo mejor os podría sonar 00:37:57
de algo 00:37:59
vuestro System.out 00:38:00
es un objeto PrintWriter 00:38:07
¿sí? 00:38:09
entonces los métodos que se encuentran 00:38:12
aquí, como por ejemplo PrintLn 00:38:14
son los que se utilizan 00:38:16
nosotros desde el primer día 00:38:18
literalmente que hemos programado 00:38:20
cuando hemos hecho System.out 00:38:22
PrintLn, System.out lo que es 00:38:24
es un objeto de tipo 00:38:26
PrintWriter, PrintLn 00:38:28
es un método de PrintWriter que me escribe 00:38:30
la string que yo 00:38:32
quiero y al final le pone un retorno de carro vale entonces el file writer 00:38:34
igualmente new file writer con la ruta del archivo para crear la cosa aquí un 00:38:41
poquito ahora os explico que quiere decir esto vale luego el print writer es un 00:38:47
nuevo print writer que sostanzialmente pilla este file writer como base el file 00:38:51
writer será el que escribe realmente el print writer es el que añade algunas 00:38:56
funcionalidades como escribir una línea eso quiere decir que escribo lo que 00:39:00
Entonces, por ejemplo, aquí lo que hace es que por 10 líneas lo que hace es escribir línea 1, línea 2, línea 3, línea 4 en un fichero, ¿vale? 00:39:03
Si explota algo, pilla la excepción, finalmente acaba, ¿vale? 00:39:14
Ten en cuenta que cuando creáis esto, el FileWriter está pensado para que tú abras un fichero y lo borres enteros y lo escribas desde el principio, ¿sí? 00:39:20
Si tú ya tienes un fichero y quieres añadir, pegar detrás cosas a ese fichero, tienes que ponerle true, lo que sea, coma true, ¿vale? Este es un parámetro que te dice, que normalmente es a false, ¿vale? 00:39:33
Que te dice si tú lo que quieres hacer 00:39:53
Cuando escribes es 00:39:55
Escribir desde el principio un nuevo fichero 00:39:56
Hasta si este ya existe 00:39:59
Borrar lo que estaba dentro 00:40:01
Y quedarte con lo nuevo 00:40:03
O si quieres hacer la operación de append 00:40:04
O sea 00:40:07
Lo que estaba, estaba 00:40:08
Y append detrás 00:40:10
Las cosas nuevas 00:40:12
¿Dudas? 00:40:13
Entonces, escritura de un archivo binario 00:40:18
Vale 00:40:20
aquí usa BufferedReader igualmente pero luego no lo debería utilizar BossWrite 00:40:21
lo escribe 00:40:29
este es un FileInputStream, BufferedInputStream 00:40:30
FileOutputStream y BufferedOutputStream 00:40:37
lo que hace es utilizar Arrays 00:40:41
entonces crea un Array de 1000 posiciones 00:40:44
hace bis.read de Array 00:40:47
este de aquí, vis.read 00:40:50
lo que hace es, te paso 00:40:52
un array, y yo 00:40:54
intento leer desde el fichero 00:40:56
hasta que el array 00:40:58
esté lleno, si hay 00:41:00
al menos 1000 bytes, leeré 00:41:02
1000 bytes de golpe, y ahora 00:41:04
tú tienes 1000 bytes, ¿por qué 1000? 00:41:06
porque aquí he puesto 1000, si pusiera 100 00:41:08
pusiera 100, ¿sí? 00:41:10
si leo menos, porque 00:41:12
en el fichero no hay 1000 bytes, hay solo 7 00:41:14
bytes, pues yo te devuelvo 00:41:16
cuántos bytes he leído, si alcanzo el final del fichero 00:41:19
antes de haber rellenado estos 1000 bytes 00:41:23
te rellenaré solo los bytes que podía, los primeros 7 bytes 00:41:26
por ejemplo, pero aquí te devuelvo cuántos he leído 00:41:31
con esto, yo puedo decir que mientras leída es mayor que 0 00:41:34
lo que hago es, esto quiere decir que he leído algo, porque si hubiese 00:41:38
0, quiere decir que no he leído nada, vale 00:41:43
Y lo que hace él es 00:41:46
Boss.write 00:41:49
Array, o sea, escribe este array 00:41:50
A partir desde la posición 0 00:41:53
Hasta la posición leído 00:41:56
Entonces si he leído 1000 00:41:58
Sería desde 0 hasta 1000 00:41:59
Si he leído 7, desde 0 hasta 7 00:42:01
¿Sí? 00:42:03
Y leídos es igual a 00:42:07
Biz.readArray 00:42:08
Esto lo leo otra vez 00:42:10
No sé por qué 00:42:12
Ah, sí, porque se prepara para la siguiente 00:42:13
vuelta de cosas. Hasta que no lea 00:42:15
nada. A ese punto, cierra 00:42:17
los dos. ¿Qué hace esta cosa aquí? 00:42:19
Y, no. 00:42:27
No hay ningún... Existe un punto, punto, punto, 00:42:32
escribirlo en otro fichero. Este es 00:42:34
copiar un fichero. Lo dice aquí. 00:42:36
Copia de un fichero. 00:42:38
Si os fijáis, 00:42:41
tiene un origen, 00:42:42
tiene una copia, 00:42:45
¿vale? Y lo que hace es 00:42:47
leer de mil en mil 00:42:48
los bytes de un fichero 00:42:50
y escribirlos en otro fichero. 00:42:52
Leo mil, escribo mil. 00:42:55
Leo mil, escribo mil. 00:42:56
Leo siete, escribo siete, acabado. 00:42:57
Hasta que no lea nada, 00:43:01
leo cero, y entonces ya está. 00:43:03
Esto es una copia a bajo nivel. 00:43:08
Estamos trabajando con arrays. 00:43:12
¿Qué es esto? ¿Un fichero de texto? 00:43:14
Me vale, me funciona. 00:43:15
¿Es un exe? Me vale, me funciona. 00:43:17
¿Es un dat? Me vale, me funciona. 00:43:20
¿Es un word? Me vale, me funciona. 00:43:23
qué estructura dinámica no sé qué me estás diciendo en fichero donde donde quieres usar 00:43:30
no esto es a byte porque la read no te pilla una rey list te pilla una rey en la en la bright no 00:43:46
te pilla una rey list te pilla una rey entonces esta es la versión básica de la cosa y no hay 00:43:58
hay una versión de la braille que te pille es ahí la puedes hacer si tú puedes crearte tu propio 00:44:06
my input stream my output stream que lo que hace es pillar de un array list pero debajo lo que hará 00:44:12
es crearte una reunión file input stream y utilizar a los arrays pero luego una vez que tú lo has 00:44:19
implementado tú desde fuera la utilizarás con lo que quieras si dudas y hasta aquí hemos llegado 00:44:24
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Primer Curso
Autor/es:
Stefano Chiesa
Subido por:
Stefano C.
Licencia:
Reconocimiento - No comercial
Visualizaciones:
15
Fecha:
27 de marzo de 2025 - 14:06
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
44′ 36″
Relación de aspecto:
16:10 El estándar usado por los portátiles de 15,4" y algunos otros, es ancho como el 16:9.
Resolución:
1152x720 píxeles
Tamaño:
107.87 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid