Saltar navegación

20260313 Ficheros_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 17 de marzo de 2026 por Raquel G.

4 visualizaciones

Descargar la transcripción

Vale 00:00:00
A ver 00:00:13
Persistencia 00:00:16
¿Vosotros qué os gusta organizar vuestra vida en temas? 00:00:19
Pues sería un tema 00:00:28
¿Vale? 00:00:29
¿Qué es la persistencia de datos? La persistencia de datos consiste en que los datos que mi aplicación maneja sean, valga la redundancia, persistentes. 00:00:31
o lo que es lo mismo 00:00:46
que yo pueda vivir despreocupada 00:00:48
de cuando mi aplicación 00:00:51
reinicia, se apaga 00:00:52
la dejo apagada 00:00:55
porque estoy instalando una versión nueva 00:00:56
lo que sea, pueda vivir despreocupada 00:00:58
de que esos datos que mi aplicación maneja 00:01:00
se van a perder 00:01:02
¿vale? 00:01:03
normalmente las aplicaciones lógicamente 00:01:06
trabajan con las colecciones 00:01:08
de usuarios, de password, de lo que sea 00:01:10
todo eso está almacenado 00:01:12
en algún sitio, sean ficheros 00:01:14
sean bases de datos. Nuestra aplicación trabaja con esos datos, pero nuestra aplicación jamás 00:01:15
trabaja con los datos directamente en el soporte de almacenamiento, sea base de datos o fichero, 00:01:21
¿verdad? Sea una base de datos o sea un fichero, que es donde realmente están los datos de 00:01:28
mi aplicación, usuarios, contraseñas, mis facturas, sean los que sean, mi programa 00:01:34
java jamás 00:01:40
va a trabajar con ellos 00:01:43
directamente aquí, es imposible 00:01:45
porque mi aplicación java 00:01:46
solamente puede trabajar 00:01:48
modificar, crear, eliminar 00:01:50
solamente puede trabajar 00:01:53
con datos que estén 00:01:55
en la memoria RAM, solamente 00:01:56
¿vale? entonces nosotros 00:02:00
hasta ahora, pues todas 00:02:02
nuestras aplicaciones 00:02:04
creaban los datos de nuevas, de buenas 00:02:05
a primeras, los creaban 00:02:08
¿Cómo? Pues insertándolos por consola 00:02:10
Los insertábamos por consola en ese momento 00:02:13
Y se creaban 00:02:15
Y ya está, entonces nuestra aplicación estaba 00:02:17
Condenada a que hubiera siempre un tío delante 00:02:19
Sentado para meter 00:02:21
Los datos y en ese momento crear los datos 00:02:23
En memoria RAM, operar y hacer 00:02:25
Lo que fuera 00:02:27
Cuando la aplicación terminaba, pues lógicamente 00:02:28
Todos estos datos 00:02:31
Pues han desaparecido 00:02:32
Luego, lo más que ha 00:02:34
Podido ocurrir es que el resultado 00:02:37
lo hayamos visto 00:02:39
en la consola 00:02:40
entonces de nuevo nuestra aplicación está condenada 00:02:42
que haya un tío ahí sentado 00:02:45
esperando que la aplicación muestre 00:02:46
las cosas en la consola para que él vaya 00:02:49
a, vale, viendo esos resultados 00:02:51
bueno 00:02:53
pues esa es una aplicación que no 00:02:54
tiene persistencia, ¿vale? 00:02:57
entonces bueno, en ciertos contextos 00:02:59
pues ya está, yo meto los datos y obtengo el resultado 00:03:01
que quería, ¿vale? no tiene persistencia 00:03:03
bueno, pero claro 00:03:05
no es lo habitual, lo habitual en una aplicación 00:03:07
es que la aplicación trabaje 00:03:09
con datos que están 00:03:11
en algún sitio, pues como hemos dicho 00:03:13
antes del tipo, un montón de facturas 00:03:15
de usuarios, de contraseñas, todo eso 00:03:17
no lo podemos introducir cada vez 00:03:19
que la aplicación arranca, lógicamente lo podemos 00:03:21
introducir, todo eso son millones 00:03:23
de datos que están en algún sitio 00:03:25
sea base de datos o fichero 00:03:27
que no se pierde nunca, ahí están 00:03:29
pero mi aplicación no puede 00:03:30
trabajar con ellos, entonces mi aplicación 00:03:33
los tiene que volcar de alguna manera 00:03:35
a variables 00:03:37
cuando ya 00:03:40
estén volcados, mi aplicación trabaja 00:03:42
con ellos 00:03:44
y cuando mi aplicación se cierra 00:03:44
de alguna manera, pues eso tiene que ir 00:03:47
otra vez al soporte 00:03:50
pues esa tarea 00:03:51
no es trivial 00:03:54
claro, esa tarea de 00:03:55
hacer esa conexión 00:03:57
esa sincronización entre lo que hay 00:03:59
aquí y lo que hay aquí, hacer esa sincronización 00:04:02
para que mi aplicación 00:04:04
trabaje con estos datos 00:04:06
sabiendo que son los que 00:04:07
realmente están aquí 00:04:10
y que cuando la aplicación termina sepa 00:04:11
que estos datos vuelven aquí 00:04:14
pues esa sincronización 00:04:16
no es trivial 00:04:17
si la conseguimos hacer 00:04:18
eso es lo que convierte a una aplicación 00:04:21
en una aplicación persistente 00:04:24
entonces una aplicación persistente 00:04:26
trabaja con sus datos en memoria RAM como todas 00:04:32
porque tienen que estar ahí, no hay otra 00:04:34
Trabaja con sus datos en RAM 00:04:36
Pero estos datos de alguna manera 00:04:38
Estarán sincronizados con los que están aquí 00:04:41
De alguna manera 00:04:43
Y ese de alguna manera 00:04:44
Pues ahí ya se abre 00:04:49
Se abre un mundo gigantesco 00:04:51
Y ese de alguna manera 00:04:54
Ese tenerlo conectado 00:04:56
Ese cómo me aseguro yo 00:04:58
Que aquello con lo que trabajo 00:05:00
Es lo que estaba aquí 00:05:01
Cómo me aseguro yo 00:05:02
Que los cambios que haga 00:05:04
Se guardan aquí 00:05:05
¿Y ese de alguna manera cómo hago esta sincronización? 00:05:06
Pues eso es un mundo gigantesco 00:05:11
y es, para que no os hagáis ilusiones, 00:05:14
no lo vamos a ver ahora, 00:05:19
porque para eso está un módulo entero de segundo 00:05:21
que es exclusivamente eso, 00:05:24
que se llama acceso a datos. 00:05:26
Entonces, este módulo de segundo es exclusivamente eso. 00:05:29
¿Por qué? 00:05:33
porque para eso hay todo un mundo entero 00:05:34
de frameworks, porque 00:05:36
de hacer bien esta sincronización 00:05:37
depende que mi aplicación 00:05:40
tenga sentido o sea una caca 00:05:42
de hacer bien esta sincronización 00:05:44
porque lo que sí que está 00:05:46
claro es que lo que no vamos a poder eludir 00:05:48
salvo en aplicaciones muy de mierdecilla 00:05:50
sencillas, lo que no vamos a poder eludir 00:05:52
es que mi aplicación trabaje con un modelo 00:05:54
de base de datos bestial 00:05:56
eso no lo vamos a poder eludir 00:05:58
que trabaje con una base de datos con tropecientas mil 00:05:59
tablas, con relaciones, con cosas. 00:06:02
Eso no se va a poder eludir. Cualquier aplicación va a 00:06:04
tener una base de datos con 30.000 tablas. 00:06:06
Entonces, la tarea 00:06:09
de yo hacer mi humilde aplicación 00:06:10
con sus variables aquí y que 00:06:12
eso automáticamente 00:06:14
quede reflejado en el soporte 00:06:15
permanente, pues eso 00:06:18
como no es trivial, hay tropecientos mil 00:06:20
frameworks. Cuando digo 00:06:24
frameworks me refiero a clases 00:06:26
que hay que configurar, que usar 00:06:28
para simular precisamente esto, 00:06:29
para simular ese efecto de persistencia, ¿vale? 00:06:33
Y eso, pues bueno, se ve todo eso 00:06:36
en este módulo entero de segundo, ¿vale? 00:06:39
Entonces, ¿aquí qué vamos a hacer ahora? 00:06:42
La parte que queda para primero 00:06:45
es como una especie de 00:06:46
yo puedo querer hacer mi persistencia si quiero, 00:06:49
es decir, quiero tener la posibilidad 00:06:52
de guardar mis cosas y que no se pierdan, 00:06:54
pero de una manera más sencilla, 00:06:57
No tengo por qué recurrir siempre a frameworks gigantescos porque no siempre tengo una base de datos con 200.000 tablas. Hombre, también quiero yo, si me hago mi aplicación con mis libros, mis cosas, pues poder guardarlo en un fichero y tenerlo ahí que cuando la aplicación arranca vuelva otra vez, ¿vale? También sería una aplicación persistente, pero hecha más a mano por nosotros, ¿vale? 00:06:58
Bueno, pues, ¿qué parte queda para primero entonces? Pues en lugar de guardar los datos en base de datos y sincronizarnos con una base de datos, hacerlo en fichero, que también puede ser perfectamente. 00:07:18
Es decir, los datos de mi aplicación 00:07:33
Estos datos que están aquí en la memoria RAM 00:07:42
Pues yo tengo mis objetos, mi lista de objetos 00:07:45
Lo que sea, lo tengo ahí 00:07:50
Yo quiero que cuando la aplicación termine eso se quede guardadito 00:07:51
Bueno, pues podemos escribirlo en un fichero 00:07:53
Y ya está 00:07:57
Cuando mi aplicación arranca yo puedo programarlo 00:07:58
Para que lo primero que haga sea si este fichero existe 00:08:02
Porque hay ya datos iniciales 00:08:05
Pues antes de nada, cárgame los que hay. 00:08:06
Y yo aquí trabajo y hago mis cosas y ya está. 00:08:08
Entonces, esto es este temita que hay ahora, 00:08:12
el de acceso a ficheros. 00:08:16
Entonces, ¿para qué nos va a servir este tema? 00:08:23
Primero, para conocer el acceso a ficheros básico, claro. 00:08:25
Y segundo, para usarlo, sobre todo, 00:08:29
que es la parte más interesante, 00:08:31
para usarlo para seguir practicando programación. 00:08:32
Para usarlo para seguir practicando lo que nos ocupa ahora, 00:08:36
que es aprender a programar y llegar a segundo programando, 00:08:39
bien, con soltura y sin perdernos 00:08:41
y sin cometer errores demasiado 00:08:43
horarios, ¿vale? 00:08:45
pues esto es lo que vamos a ver ahora 00:08:48
acceso a ficheros desde 00:08:49
mis aplicaciones Java 00:08:51
¿vale? el acceso a bases 00:08:52
de datos 00:08:55
lo dejamos así en gordote 00:08:56
para el curso que viene 00:08:59
vale, pues venga 00:09:01
bueno, pues ya sabéis que cualquier aplicación Java 00:09:06
es un montón de clases que hacen cosas 00:09:20
ya lo sabéis 00:09:22
o bien clases que ya están 00:09:23
en la JRE 00:09:25
y que yo uso, pues como la clase 00:09:28
Scanner que hemos usado, la clase 00:09:30
ArrayList, la clase 00:09:32
LinkedList, o bien clases que ya están y que yo 00:09:34
uso, o bien clases que me invento 00:09:36
yo, ¿vale? Pero en la gran mayoría 00:09:38
de las veces lo que hacemos es usar clases que ya están 00:09:40
hechas y esas clases me ofrecen 00:09:42
métodos para hacer cosas. Bueno, 00:09:44
pues eso es lo que vamos a hacer aquí. 00:09:46
Conocer las clases básicas 00:09:48
que ya están hechas 00:09:50
y que me permiten hacer cosas con 00:09:51
ficheros, escribir en ellos 00:09:54
leerlos, etc. 00:09:56
Todas esas clases que ya están hechas 00:09:57
pues de toda la vida 00:09:59
estaban en un 00:10:02
paquetito 00:10:05
que es Java.io que está 00:10:06
en la JRE, con lo cual no tenemos que 00:10:09
importarlo 00:10:11
y luego se incorporaron algunas 00:10:12
modificaciones, algunas 00:10:17
clases nuevas 00:10:19
en Java.io 00:10:20
para optimizar 00:10:23
el uso de las 00:10:24
clases de esta de aquí, pero vamos 00:10:27
esencialmente el funcionamiento es el mismo 00:10:29
y estas son las básicas 00:10:30
¿vale? pero bueno, vamos a mencionar un poquito 00:10:33
las clases 00:10:35
básicas de las dos son las que vamos a 00:10:36
mencionar y ya está, ¿vale? estos serían los dos 00:10:39
paquetes, para que nos pongamos 00:10:41
en contexto, que tienen las clases básicas 00:10:43
para acceder a ficheros, serían 00:10:45
estos dos, ¿vale? 00:10:47
bueno, pues un poquito por encima, ¿qué clases 00:10:51
hay ahí? ¿qué tenemos? 00:10:53
vale, pues si yo quiero trabajar 00:10:56
con un fichero 00:10:57
necesito 00:10:58
un objeto que me lo represente 00:11:00
porque en Java 00:11:02
todo lo que puede hacer lo tiene que hacer 00:11:03
con objetos, todo, es que no hay otra 00:11:06
lo tiene que hacer con objetos 00:11:08
bueno, pues si yo necesito un fichero que es mi primer 00:11:09
mi primer recurso 00:11:12
ajeno a la aplicación, trabajar con él 00:11:14
pues necesito un objeto Java 00:11:16
que me lo represente asociado a él 00:11:18
y yo trabajo con ese objeto Java 00:11:20
vale, pues ¿cuál es la clase Java 00:11:21
que representa 00:11:24
el objeto fichero? 00:11:30
File, la clase file de java.io es la clase java que representa un objeto fichero, entonces yo quiero trabajar con un fichero para pasárselo como parámetro a un método para que haga cosas con él, para hacer cosas con él, pues lo que suelo hacer es instanciar un objeto file asociado a ese fichero, ¿vale? 00:11:31
Asociado a ese ficherito 00:11:52
Y ahora ya la clase file 00:11:55
Este objeto que yo instancio 00:11:58
Asociado a este ficherito 00:11:59
Pues ya me ofrece 00:12:00
Un montón de métodos para hacer unas cuantas cosas 00:12:02
¿Vale? Pues por ejemplo 00:12:06
Ver si existe, ver que permisos tengo 00:12:09
Sobre él 00:12:11
En general me permite 00:12:12
Me ofrece a través de los métodos 00:12:14
Información sobre este fichero 00:12:17
Información, no todavía lecturas y escrituras 00:12:19
no, información sobre 00:12:22
el fichero, ¿vale? 00:12:24
cambiarle el nombre 00:12:25
borrarlo, cosas así 00:12:26
entonces esta es la clase 00:12:30
básica, en general 00:12:32
cuando un método o lo que sea necesita un fichero 00:12:34
para trabajar se le pasa en 00:12:36
objeto file, ¿vale? 00:12:37
el equivalente a este en java.new 00:12:42
sería el objeto 00:12:44
path, ¿vale? pero bueno 00:12:47
luego según vayamos viendo los ejemplos 00:12:50
pues lo iremos viendo 00:12:52
entonces los dos nombres 00:12:54
están bien escogidos 00:12:58
cada uno con su matiz 00:13:00
o sea este está bien escogido 00:13:01
porque representa un fichero 00:13:03
entonces pues mira file 00:13:06
representa un fichero y se llama file, que bien 00:13:07
pero este está bien escogido 00:13:09
también porque pone de manifiesto 00:13:11
lo que identifica un fichero 00:13:13
en realidad, a un fichero lo identifica 00:13:16
su nombre por supuesto 00:13:18
pero toda la ruta en la que está 00:13:20
del sistema de archivos, eso es lo que identifica 00:13:22
un archivo, su nombre y toda su 00:13:24
ruta 00:13:26
un recurso archivo 00:13:26
se identifica de forma única solamente 00:13:29
con toda su ruta además de su nombre 00:13:32
porque puede haber ficheros que se llaman 00:13:34
igual en rutas distintas 00:13:36
entonces la única forma de identificar de forma única un fichero 00:13:37
es toda su ruta con su nombre 00:13:40
y eso es lo que tenemos que saber 00:13:41
para instanciar el objeto file, etc 00:13:44
entonces quizá este nombre 00:13:45
es casi más bonito porque nos hace ver 00:13:47
que un fichero en realidad es toda una ruta 00:13:50
en mi sistema de archivo, no es un nombre 00:13:51
sin más, esto es una ruta 00:13:54
bueno, pues clase file, ¿qué más clases 00:13:55
vamos a ver? ahora antes de ponernos con los ejemplos 00:13:59
bueno, pues aparte de 00:14:02
instanciar un objeto archivo para tener información 00:14:03
sobre él, para pasárselo como parámetro 00:14:05
a un método, para que haga lo que sea, etc 00:14:07
nos interesa 00:14:09
leer y escribir en los 00:14:11
archivos, es esencialmente lo que nos interesa 00:14:13
vale 00:14:16
pues, vale, para 00:14:18
leer y escribir en un archivo 00:14:26
Java lo organiza mediante 00:14:28
flujos 00:14:31
¿vale? flujos o 00:14:32
en terminología Java Neo ya es más 00:14:36
canales, channels, pero bueno 00:14:38
es la misma idea, un stream 00:14:40
un channel, es la misma idea, es como hacer una pequeña 00:14:42
tubería hacia ese fichero 00:14:44
entonces 00:14:46
nuestra aplicación lo que hará será 00:14:49
leer de esa 00:14:52
tubería, pi pi pi, por aquí se van 00:14:54
enviando los bytes, por aquí van los bytes 00:14:56
y se va leyendo de esa tubería 00:14:58
entonces, ¿quién es capaz de leer 00:15:01
de esa tubería? 00:15:03
pues hay dos clases 00:15:06
asociadas a sacar información 00:15:07
de esa tubería o channel o canal básico 00:15:10
en javaío 00:15:12
estoy situada ahora, pero bueno 00:15:14
es más o menos la que se ha usado siempre 00:15:16
pues file input stream 00:15:18
sería directamente para sacar bytes 00:15:27
uno tras otro 00:15:32
y file reader 00:15:33
sería 00:15:39
para también sacar bytes 00:15:41
uno tras otro, pero 00:15:44
devolvermelos convertidos a char 00:15:46
interpretados como si fueran un char 00:15:48
entonces si yo sé que es un fichero de texto 00:15:49
directamente le asocio un file 00:15:51
reader, que me va a permitir ir sacando 00:15:54
los char tal cual 00:15:56
si yo no sé lo que hay ahí, que es un fichero 00:15:57
binario, pues le asocio un file 00:16:00
input string, y voy sacando los bytes 00:16:02
uno tras otro, a ver aquí estoy 00:16:04
en el bajo nivel completamente 00:16:07
estas son las clases de más bajo nivel que hay posibles 00:16:09
que me sacan directamente los bytes 00:16:11
luego claro 00:16:13
sobre esto 00:16:15
ya se pueden montar 00:16:16
clases más complejas para envolverme 00:16:19
en la complejidad y pues yo quiero 00:16:21
sé que tiene números enteros 00:16:23
pues léeme directamente enteros 00:16:25
entonces tendrá que leer 4 bytes 00:16:26
entonces sobre esto ya 00:16:28
hay clases 00:16:30
más complejas que se montan 00:16:32
para hacer cosas más sofisticadas 00:16:35
Pero que se apoyan sobre estas 00:16:37
Sobre las básicas 00:16:39
Que son estas dos 00:16:40
¿Vale? 00:16:41
Entonces si lo que yo quiero 00:16:44
Es en lugar de leer bytes 00:16:45
Escribir bytes 00:16:48
¿Vale? Pues las clases serían 00:16:49
Adiós 00:16:52
Serían file 00:16:56
Serían file output 00:16:57
Stream 00:17:03
O file writer 00:17:04
Bueno estas serían como las 5 básicas 00:17:07
Las de bajo nivel 00:17:12
Vamos a usarlas ahora 00:17:14
Antes de contar más historias 00:17:16
Vamos a usarlas ahora para hacer algún ejemplo 00:17:17
Y así pues seguimos programando 00:17:20
Un poquito y ya está 00:17:22
¿Vale? Antes de 00:17:24
Seguir hablando 00:17:26
Achar, claro 00:17:27
Coge los ceros y unos tal cual 00:17:42
Input es para 00:17:51
llevar de fichero a variable 00:17:52
y output es 00:17:55
para llevar de variable a fichero 00:17:57
¿vale? 00:17:59
vamos a verlo ahora 00:18:01
en un ejemplo 00:18:03
los de DAO sueñan mucho por las noches 00:18:05
no les hagan ni caso 00:18:24
obviamente 00:18:27
después de semana santa habrá un examen 00:18:34
pero no sabemos si dos días después o tres meses después 00:18:36
O sea, lo que han dicho 00:18:38
Estrictamente falso no es 00:18:41
Pero vamos, que no tenemos en mente 00:18:43
Ningún examen todavía, más allá de cuando 00:18:49
Tengo que hacer un examen, porque en mayo hay que hacer exámenes 00:18:51
Claro 00:18:53
Pero es que realmente, tampoco puede ser mucho después 00:18:54
Porque es que tenemos un 00:18:57
Problemón 00:18:59
Los ficheros 00:19:00
Ejemplos 00:19:05
Vale 00:19:08
Porque volvemos de Semana Santa 00:19:14
pues el 6 de abril 00:19:19
puede ser, el 7 de abril 00:19:22
el 7 de abril 00:19:24
evaluación vuestra 00:19:33
es el 18 de mayo 00:19:36
con lo cual 00:19:38
del 11 00:19:40
entonces tenemos un mes 00:19:42
vale, pues venga 00:19:44
Este porque se me pone 00:19:50
Vale 00:19:54
Pues venga 00:20:01
Vamos a hacernos un paquete 00:20:03
Por aquí 00:20:05
Primero para trabajar 00:20:08
Ejemplo con texto 00:20:10
Que es la forma 00:20:13
La forma más fácil de 00:20:14
Entenderlo de buenas a primeras 00:20:17
Venga, contexto 00:20:19
Pues ahora vamos a hacernos 00:20:22
Un programita 00:20:24
¿Por qué no me aparece 00:20:26
Aquí lo de 00:20:40
Ah, es que 00:20:41
Me parece bien pequeñito 00:20:43
Vale, pues venga 00:20:48
Pues venga, por ejemplo 00:21:07
Vamos a hacer una 00:21:11
minimísima aplicación 00:21:13
que trabaja con nombres 00:21:16
de personas 00:21:17
entonces esos nombres de personas 00:21:18
para trabajar con ellos tendrían que estar 00:21:22
guardados en algún sitio 00:21:23
pues vamos a guardarlos por ejemplo aquí 00:21:24
en una lista 00:21:27
vale 00:21:30
vale 00:22:04
pues a ver 00:22:09
vamos a hacer un bucle 00:22:09
que le ha 00:22:16
solicite nombres y los guarde 00:22:18
luego al final, antes de irse, los guarde en el fichero 00:22:20
vale 00:22:23
pues yo tengo aquí mi nombre 00:22:23
y ahora 00:23:05
a nombres.add 00:23:07
scan.nextline 00:23:10
vale, pues aquí 00:23:15
nosotros ya podemos procesar 00:23:24
los nombres, hacer lo que sea 00:23:26
lo que sea que mi aplicación 00:23:29
hiciera con esos nombres 00:23:33
lo que fuera 00:23:34
pero antes de irme, yo ya de mi aplicación 00:23:35
Antes de procesar los nombres 00:23:44
Yo los 00:23:46
Vale 00:23:48
Los quiero dejar 00:23:52
Vale, los quiero dejar guardados 00:23:53
En un fichero 00:23:59
Venga, pues me voy a hacer ahora aquí un método 00:23:59
Guardar nombres 00:24:05
Al que le 00:24:07
No hace falta que le pase 00:24:09
Mis nombres, porque como están como variable local 00:24:11
Vale, guardar nombres 00:24:13
Venga, vamos a hacernos este método 00:24:16
Bueno 00:24:18
Pues proceso para guardar en un fichero 00:24:33
Proceso para guardar en un fichero 00:24:36
Primero 00:24:39
Abrir el fichero 00:24:40
Para escritura 00:24:45
Para escritura 00:24:46
Después de que lo hayamos abierto 00:24:49
Haremos las escrituras 00:24:53
Escribimos 00:24:56
Y después de que hemos escrito 00:24:57
Cerramos 00:25:02
¿Vale? 00:25:03
Estos son los tres pasos 00:25:05
Abrimos el fichero, escribimos y cerramos 00:25:09
Vale 00:25:12
Abrir el fichero 00:25:13
¿Qué significa? 00:25:16
Instanciar el objeto que corresponda 00:25:18
Para 00:25:20
Abrir un fichero para leer de él 00:25:22
Entonces 00:25:24
En este caso 00:25:26
Mi fichero va a ser de texto 00:25:28
Porque yo voy a guardar caracteres que luego quiero leer como texto 00:25:29
Entonces para leer 00:25:32
Tendríamos dos alternativas 00:25:34
Estando a nivel básico 00:25:35
El más básico posible 00:25:38
El más tocando el bajo nivel 00:25:39
File input, perdón 00:25:41
Para escritura 00:25:43
File output stream 00:25:45
Output es salir, salgo del fichero 00:25:46
O sea, perdón, salgo de la aplicación 00:25:49
Output significa salgo de la aplicación 00:25:51
De mi aplicación me voy fuera 00:25:53
Pues file output stream 00:25:55
Para mandar bytes tal cual 00:25:57
O file writer 00:26:00
Que sería en mi caso el que aplicaría 00:26:02
Porque estoy escribiendo cosas que son caracteres 00:26:05
Entonces, opciones que tenemos a nivel básico tendríamos, repito, esta para escribir bytes sin más, o sea, bytes, y esta otra que he dicho, escribir caracteres. 00:26:07
En nuestro caso es lo que queremos, pues entonces toca instanciar este objeto, que este es el que toca, toca este. 00:26:37
vale, siempre lo mismo, abrimos el fichero 00:26:43
escribimos o leemos 00:26:47
si estuviéramos en lectura y cerramos 00:26:49
vale, y abrir significa 00:26:50
instanciar el objeto 00:26:53
que toque, pues para escribir 00:26:55
en un fichero de caracteres 00:26:58
FileWriter, para escribir bytes 00:26:59
sin más, sin interpretar 00:27:02
la información, FileOutputStream 00:27:04
en este caso caracteres 00:27:05
vamos a instanciarlo 00:27:07
FileWriter, vale 00:27:08
como instanciamos un objeto 00:27:13
normalmente con el 00:27:17
constructor, a menos que tengamos 00:27:19
método que llame al 00:27:22
constructor, en este caso con el constructor 00:27:25
vale, y ahora 00:27:27
a FileWriter, ¿qué hay que pasarle al 00:27:29
constructor? hay que pasarle 00:27:31
el fichero en el 00:27:33
que vamos a escribir, eso es lo que hay que pasarle 00:27:35
hay que pasarle el fichero en el que vamos a escribir 00:27:37
porque este objeto FileWriter 00:27:39
se asociará a un fichero 00:27:41
este FileWriter será como ese flujo 00:27:43
ese canal 00:27:45
Entonces ahí hay que pasar el fichero 00:27:47
Se puede pasar de dos maneras 00:27:49
El nombre del fichero sin más 00:27:52
Con toda su ruta, por supuesto 00:27:54
Es decir, un string 00:27:56
O el objeto file que lo representa 00:27:57
El constructor está sobrecargado 00:27:59
Entonces, por ejemplo 00:28:03
Vamos a preguntar aquí 00:28:04
En qué fichero quiere guardarlo 00:28:09
En qué fichero quiere guardar 00:28:11
ahora aquí nos dirá el nombre del fichero 00:28:20
me voy a coger el escáner de arriba 00:28:29
aquí estoy 00:28:42
vale, este es el nombre del fichero 00:28:48
en el que quiere guardar 00:28:55
vale, entonces 00:28:57
yo puedo pasar el nombre del fichero 00:28:58
directamente aquí 00:29:01
si quiero 00:29:03
vale 00:29:04
puedo pasar directamente el nombre del fichero 00:29:05
y ya está 00:29:08
este flujo se asociará a ese fichero 00:29:09
ya se quedaría abierto 00:29:12
se quedaría abierto 00:29:13
cuidado 00:29:14
si esto es el nombre del fichero sin más 00:29:16
recordad que un recurso fichero 00:29:19
no se queda identificado por su nombre 00:29:21
no, así se queda ambiguo 00:29:23
porque puede llamarse un fichero igual 00:29:25
en muchos sitios de mi sistema de archivos 00:29:27
entonces si yo paso el nombre 00:29:29
sin más 00:29:31
lo que asume la clase 00:29:32
FileWriter es que entonces 00:29:34
la ruta en la que está 00:29:36
ese fichero, la ruta es 00:29:39
la raíz del proyecto 00:29:41
es decir, esto 00:29:42
¿vale? si yo paso aquí el nombre sin más 00:29:44
él asume que entonces la ruta 00:29:49
es la de la raíz 00:29:51
del proyecto, esa es la ruta que se llama 00:29:52
por defecto de cualquier aplicación Java 00:29:54
la ruta raíz de la cual 00:29:56
cuelgan todos los paquetes 00:29:58
¿vale? entonces yo puedo hacer 00:30:00
ahora mismo mi método 00:30:04
así, pasando directamente el nombre 00:30:05
y ya está, veréis que el fichero 00:30:07
me aparece aquí 00:30:09
me aparece ahí en esa ruta 00:30:11
Que yo no quiero que sea esa ruta 00:30:13
Sino otra 00:30:16
Pues le tengo que pasar aquí 00:30:17
El string con toda la ruta 00:30:19
Enterita, toda 00:30:22
El c, dos puntos, barra, etc 00:30:23
¿Vale? 00:30:25
Esa es una ruta absoluta 00:30:27
¿Es obligatorio que yo pase siempre rutas absolutas? 00:30:29
No, no eso no es obligatorio 00:30:33
Si es que ni siquiera es deseable 00:30:34
Porque una aplicación 00:30:36
Que está basada en rutas absolutas 00:30:38
Que tú cuando 00:30:40
en esa aplicación haces accesos 00:30:41
a fichas de frutas absolutas, es muy poco 00:30:43
portable, lógicamente 00:30:45
porque yo puedo poner aquí 00:30:47
C, dos puntos, uses, Raquel, bla bla bla 00:30:48
y ahora te doy mi aplicación 00:30:51
para que tú la ejecutes en tu equipo 00:30:53
cuando esa aplicación intente abrir 00:30:55
el recurso C, uses, Raquel 00:30:57
va a decir esta ruta aquí no existe 00:30:59
entonces no es 00:31:01
de hecho es absolutamente desaconsejable 00:31:02
jamás lo hacemos lógicamente 00:31:06
usar rutas 00:31:07
absolutas para identificar 00:31:09
ubicaciones de ficheros 00:31:11
porque esa ruta va a perder validez 00:31:13
en cuanto tú muevas la aplicación 00:31:16
a otro equipo 00:31:17
entonces, ¿qué es lo que podemos 00:31:18
poner? rutas relativas 00:31:21
relativas a 00:31:24
cual a este 00:31:26
rutas relativas, entonces si yo pongo 00:31:26
por ejemplo 00:31:29
carpeta 00:31:30
hola barra nombre del fichero 00:31:36
pues la carpeta hola se sobreentiende 00:31:38
que está aquí dentro, es una ruta 00:31:40
relativa, si yo hago ahora el 00:31:42
dos puntos, recordáis que con dos puntos 00:31:44
te subes un 00:31:46
piso por encima del sistema de archivos 00:31:47
¿verdad? vale, pues si yo pongo 00:31:49
la ruta dos puntos, barra, no sé 00:31:52
qué, pues me he subido por 00:31:54
encima de mi ruta 00:31:56
por defecto que es esta 00:31:58
y ahí ya me he ido a la carpeta, entonces siempre puedo 00:32:00
hacer rutas relativas 00:32:02
a esta, ¿vale? 00:32:04
Que es lo deseable, rutas relativas a esta 00:32:06
Y esas ya sí que van a funcionar 00:32:08
Pase yo mi aplicación a donde la pase 00:32:11
¿Vale? 00:32:13
Y siempre deberían tener rutas relativas 00:32:15
Claro 00:32:17
Bueno, aquí nosotros, como vamos a pasar el nombre sin más 00:32:17
Pues eso significa 00:32:20
Que mi fichero va a aparecer aquí 00:32:23
¿Vale? Estupendo 00:32:24
Bueno, pues 00:32:25
Yo puedo pasar aquí el nombre sin más 00:32:28
Pero este constructor 00:32:30
También permite que yo le pase 00:32:32
el objeto file asociado 00:32:35
a este 00:32:37
¿vale? pero bueno, con el objeto file 00:32:37
lo ponemos 00:32:41
como ejemplo ahora en otro método 00:32:43
bueno, pues ya está, esto ya está 00:32:44
se me ha aparecido en rojo, ¿por qué? 00:32:47
porque 00:32:50
FileWriter puede lanzarme 00:32:50
una excepción y esta sí que no es 00:32:53
runtime excepción, esta es una excepción 00:32:55
de verdad 00:32:57
¿vale? si nosotros entramos en la clase 00:32:58
FileWriter, ¿veis? 00:33:01
tiene un 00:33:08
throws io exception 00:33:10
es decir 00:33:12
puede que yo me encuentre un problema 00:33:14
de entrada y salida cuando trato de instanciar 00:33:16
el flujo, puede que yo me 00:33:18
encuentre io exception 00:33:20
si entráramos en ella 00:33:22
bueno, esto 00:33:23
me va a tardar 00:33:28
veré que hereda de exception 00:33:33
no de runtime exception, pero no me la 00:33:38
no me llega a abrir la 00:33:40
jerarquía esta 00:33:45
¿cuál es la diferencia? 00:33:47
bueno, la que hemos visto 00:33:52
en las clases anteriores 00:33:56
si una excepción hereda de excepción 00:33:57
eso implica 00:34:00
que es como de mayor rango 00:34:02
y es automáticamente de obligada 00:34:03
captura o propagación 00:34:06
donde tú la llames 00:34:07
bueno, tú la has decidido 00:34:08
por programa 00:34:11
entonces, se supone que son excepciones 00:34:12
que es más 00:34:15
peligroso que te aparezcan en tiempo de ejecución 00:34:17
entonces ya desde tiempo de compilación 00:34:20
obligas al que desarrolla el código 00:34:22
a pronunciarse sobre si te sale 00:34:24
¿vale? entonces es una cuestión de diseño 00:34:26
de categoría de excepciones que yo no quiero 00:34:28
dejar, no quiero arriesgarme 00:34:30
a que aparezcan en tiempo de ejecución 00:34:33
porque sí ¿vale? 00:34:34
entonces las que tú haces que hereden de exception 00:34:36
o las que están hechas 00:34:38
que hereden de exception, la máquina virtual 00:34:40
como esta, la de 00:34:42
io exception, se supone que esa es 00:34:44
lo suficientemente, porque claro 00:34:46
si tú cuentas que tu aplicación va a abrir un fichero 00:34:48
y luego no puede abrirlo 00:34:50
pues te la has cargado entera 00:34:51
entonces tiene sentido que ya de partida 00:34:53
cuando yo hago aquí 00:34:56
esto 00:34:57
me diga 00:34:59
ojo, que esto puede que te encuentres 00:35:02
un problema, que este fichero no lo pueda 00:35:04
abrir porque tengo que hacer el tema de archivos 00:35:06
dime que hago si no 00:35:07
entonces ya directamente 00:35:08
tú ya dices, pues hago un try catch 00:35:12
y ya doy una alternativa 00:35:14
¿vale? 00:35:16
Array in this auto bound exception 00:35:17
esa no hereda de excepto, hereda de runtime 00:35:19
entonces esa no tenemos que 00:35:22
capturarla todo el rato, ¿por qué? porque asumimos 00:35:24
que esa excepción no va a salir 00:35:26
porque si sale es porque has hecho el código fatal 00:35:28
entonces vale, que te salga y lo arreglas 00:35:30
pero esta no es que no depende del programador 00:35:32
esta te puede salir por un problema 00:35:34
ajeno al programador, entonces 00:35:36
te avisa desde ya 00:35:37
para que digas, oye, si pasa esto que no es 00:35:39
tu culpa, pero podría ocurrir, ¿qué haces? 00:35:42
y tú como programador lo arreglas, ¿vale? 00:35:44
bueno, pues entonces 00:35:51
aquí efectivamente me dice, oye, cuidado 00:35:52
que te podría salir un io exception 00:35:54
porque yo no te prometo 00:35:56
que el fichero esté disponible 00:35:58
¿qué haríamos si no? ¿qué haríamos? 00:36:01
Bueno, pues recordad que cuando 00:36:04
tú tienes el aviso de que hay 00:36:06
una excepción que te puede salir, tienes dos opciones 00:36:08
fea y la bonita 00:36:12
la bonita 00:36:15
es capturar y decir, voy a 00:36:16
dar yo una solución 00:36:18
¿vale? voy a dar yo una solución 00:36:19
Capturar, ya sabemos que es esta 00:36:22
¿Vale? 00:36:25
Entonces, si no puedo instanciar el objeto 00:36:27
Si no puedo instanciarlo 00:36:30
Pues aquí digo lo que sea 00:36:32
O digo, elige otro nombre de fichero 00:36:34
Lo que sea 00:36:37
Ya lo que yo decida 00:36:38
Error al acceder al archivo 00:36:40
Se usará uno por defecto 00:36:48
Lo que sea, lo que yo decida 00:36:51
pero ya sé que mi aplicación no para 00:36:53
que eso es lo bueno, mi aplicación no va a parar 00:37:01
¿vale? ya sé que mi aplicación no va a parar 00:37:03
mi aplicación seguirá por aquí 00:37:05
en función 00:37:08
de lo que yo siga haciendo 00:37:10
me habré creado un archivo por defecto, lo que yo quiera 00:37:11
vamos, lo que yo quiera 00:37:13
¿cuál era la opción mala? 00:37:14
la opción mala 00:37:21
depende de donde esté yo, claro 00:37:22
pues estoy programando en plan rápido 00:37:24
estoy en una aplicación, quiero hacer pruebas cuanto antes 00:37:30
no quiero que me quede un código muy engorroso 00:37:32
tengo la seguridad de que no va a haber ningún problema 00:37:34
con mi sistema de archivos 00:37:36
pues la es 00:37:37
pues propago, de las dos opciones que tengo 00:37:39
que son 00:37:42
o capturar con el 00:37:43
try catch o propagar 00:37:46
pues propagar 00:37:48
y propagar que significa 00:37:49
pues propagar significa en el método 00:37:51
donde esa excepción puede salir 00:37:54
en el método donde puede salir 00:37:57
sea el que sea 00:37:58
avisas 00:37:59
vale 00:38:01
entonces 00:38:03
esta puede ser fea 00:38:09
como digo yo, no, depende 00:38:12
en este caso no es tan fea porque 00:38:14
el mes 00:38:16
lo que haría no sería parar el programa 00:38:18
sino el aviso 00:38:21
propagarlo para que lo dé este 00:38:22
entonces el aviso ahora ya salta y se queda 00:38:24
aquí, entonces todavía 00:38:27
me queda una oportunidad de try catch 00:38:28
todavía me queda una oportunidad de try catch que es aquí arriba 00:38:30
entonces aquí todavía 00:38:33
no he actuado tan mal 00:38:34
no he actuado tan mal 00:38:36
porque lo que he dicho es, oye, cuidado 00:38:38
que puede que salga un error 00:38:40
como yo no soy 00:38:42
el programa principal 00:38:44
todavía, como yo no soy el programa principal 00:38:47
aviso arriba 00:38:49
propago con el 00:38:51
el aviso llega aquí 00:38:53
y aquí todavía 00:38:55
tengo una oportunidad de try catch 00:38:57
¿vale? para decir, oye 00:38:59
no se ha podido guardar nombres 00:39:01
Bueno, pues aquí todavía tengo una oportunidad de try-catch 00:39:02
Y aquí ya sí que haría 00:39:05
No se han 00:39:08
Podido 00:39:18
Guardar 00:39:19
Y al menos el que ha trabajado 00:39:20
Con estos nombres sabe que los ha perdido 00:39:23
O si no 00:39:25
Se puede meter en un bucle 00:39:27
Y lo que sea, lo que uno decida 00:39:29
¿Vale? 00:39:31
Aquí lo que sí que sería feo 00:39:42
Es aquí seguir propagando 00:39:44
Porque aquí ya tengo el main 00:39:46
vale, entonces 00:39:47
si aquí yo 00:39:49
ante este aviso 00:39:53
de guardar nombres 00:39:56
de cuidado, que puede salir una excepción 00:39:58
vale 00:39:59
ante este aviso 00:40:02
yo dijera, bueno, voy a 00:40:03
seguir pasando el aviso hacia arriba 00:40:06
porque tengo dos opciones, o ahora ya 00:40:07
capturo o lo sigo pasando hacia arriba 00:40:09
pues si yo opto por no 00:40:11
emborronar el código y porque no me quede feo 00:40:13
opto por, venga, pues vamos 00:40:15
para arriba, ahora 00:40:17
haya el Throws, ¿quién lo está 00:40:19
lanzando? El Main. 00:40:21
Y esto ya sí que no. 00:40:23
A menos que esté todavía en fase de pruebas, 00:40:25
haciendo mis cosas. Esto ya sí que no. 00:40:27
Porque cuando es el Main 00:40:29
el que tiene el Throws, cuando 00:40:31
la excepción llega, ¿qué ocurre? 00:40:33
El programa se para. Porque el Main ya no tiene 00:40:35
nadie a quien delegar 00:40:37
y seguirle. El Main ya no tiene nadie. 00:40:39
Es el método 00:40:42
raíz. Entonces, si yo propago 00:40:43
y le digo, oye, guardar nombres, 00:40:45
si te da un error, 00:40:47
propaga, el main dice 00:40:49
uy, pues yo soy el último 00:40:51
yo soy el último, no puedo propagárselo a nadie 00:40:52
para que el de arriba decida si try catch o no 00:40:55
yo soy el último, pues programa se para 00:40:57
entonces que el main tenga un 00:40:59
throws o 00:41:01
cualquier clase principal 00:41:02
pues hombre, ahí ya sí que 00:41:04
cuando estamos todavía 00:41:07
en fase de desarrollo vale, porque no tengo 00:41:09
tantos try catch, pero no debería 00:41:11
¿y lo mejor es hacer el try catch cuando 00:41:13
cuando primero aparece? 00:41:15
es que depende, depende de 00:41:17
si lo que yo estoy haciendo es un paquete 00:41:19
depende del diseño que haga 00:41:21
vale, pues entonces este throws 00:41:22
aquí sí que no nos gusta 00:41:26
nada, y aquí ya 00:41:28
sí que lo pondríamos, intenta 00:41:34
guardar, dejo 00:41:36
el print extract trace porque estoy todavía 00:41:40
en fase de desarrollo, pues para que 00:41:41
me dé datos técnicos 00:41:44
bueno, pues la excepción la tenemos 00:41:47
ya resuelta, la excepción la tenemos 00:41:55
resuelta, ya hemos podido 00:41:59
crear nuestro flujo 00:42:01
y ahora ya 00:42:02
este flujo nos permite escribir 00:42:04
¿vale? ahora ya se trata 00:42:06
de ver qué métodos me ofrece 00:42:09
y cuál me interesa, ya está, cuál me interesa 00:42:10
¿qué métodos me ofrece? 00:42:13
pues un montón 00:42:14
si vemos ahí lo que nos ofrece, pues un montón de cosas 00:42:15
pues nos ofrece 00:42:22
un montón de métodos, ¿vale? 00:42:31
el file writer 00:42:33
en particular relacionado con 00:42:34
escritura, los write, pues puedes 00:42:37
mandar un array de chat de golpe 00:42:39
Puedes mandar un string de golpe 00:42:41
¿Vale? 00:42:44
Puedes mandar 00:42:46
Esto lo entenderemos mejor 00:42:47
Cuando veamos la lectura 00:42:50
Esto no significa que has mandado un número entero 00:42:51
No, tú le mandas una variable entera 00:42:53
Y él lo que guarda es el último byte 00:42:55
De los cuatro, el menos significativo 00:42:58
Porque interpreta 00:43:00
Que ahí es donde está el char 00:43:02
¿Vale? 00:43:03
¿Por qué de esta manera tan extraña? 00:43:05
En lugar de un solo char 00:43:07
Para luego poder sincronizarse con el de leer 00:43:08
Luego con la lectura lo veremos 00:43:10
¿Vale? Pero no significa que puedas guardar un número 00:43:12
No, es un único char, lo que guardas es que está en el byte menos significativo 00:43:14
Entonces, pues hombre 00:43:17
Este parece bastante útil 00:43:18
Con este puedes mandar un string enterito 00:43:20
Pues venga, vamos a 00:43:21
A usar este 00:43:24
¿Vale? 00:43:26
Vamos a usar este, pero vamos a tener que hacer un bucle 00:43:28
Para poder escribir todos 00:43:30
Pues venga 00:43:32
Para cada 00:43:34
Nombre 00:43:35
nombres 00:43:41
para cada nombre 00:43:43
nombres, ala, escribe 00:43:49
escribir un fichero 00:43:52
de texto, pues lo más fácil del mundo 00:43:54
vale, esto ya está 00:43:56
cada write 00:44:01
cada ejecución de write 00:44:02
escribe y deja posicionado 00:44:05
el fichero internamente para que los siguientes 00:44:07
se escriban abajo, claro, no se lo escribe todo el rato 00:44:09
¿qué parámetro? 00:44:11
no, porque es n 00:44:15
¿lo pw era? 00:44:17
era este objeto 00:44:21
que acabo de crear 00:44:23
entonces 00:44:24
inicialmente 00:44:29
a ver, este constructor 00:44:33
tiene un segundo parámetro 00:44:34
que yo puedo usar o no 00:44:36
que es 00:44:39
si yo quiero añadir 00:44:40
en el fichero por si yo hubiera algo antes 00:44:42
porque puede ser que ese fichero 00:44:45
que yo abro para escribir 00:44:46
ya tenga algo de antes 00:44:48
pues puede ser que yo quiera añadir 00:44:49
o eliminar todo lo que hubiera y hacerlo de nuevas 00:44:52
entonces este parámetro de aquí 00:44:54
este segundo parámetro del constructor 00:44:57
es un boolean 00:45:00
que yo lo puedo usar 00:45:01
si lo pongo a true 00:45:03
significa que lo quiero en modo añadir 00:45:04
vale 00:45:07
entonces vamos a ponerlo ahí 00:45:08
el segundo parámetro del constructor 00:45:11
me indica 00:45:15
si quiero 00:45:20
añadir o borrar 00:45:21
si no pones nada por defecto es 00:45:24
falso, te lo haría 00:45:30
de limpio el fichero, te sobreescribiría 00:45:32
o sea, te borraría 00:45:34
todo lo anterior y lo empezaría de cero 00:45:36
se atrúes para 00:45:37
añadir 00:45:39
eso 00:45:41
lo que hubiera 00:45:42
previamente, vale, vamos a 00:45:45
poner lo que añada y ya está 00:45:50
vale, una vez que ya hemos 00:45:51
escrito 00:45:56
hay que cerrar el flujo 00:45:57
si no lo cerramos 00:46:00
cuando el programa acabe se va a cerrar igualmente 00:46:02
pero si el programa no termina 00:46:05
porque hace más cosas y yo no lo cierro 00:46:07
el fichero se queda bloqueado 00:46:08
y si algún otro proceso quisiera trabajar con él 00:46:11
pues no podría 00:46:13
entonces siempre hay que cerrar los flujos 00:46:13
que se abren, claro 00:46:17
pues ya está, vamos a probarlo rápidamente 00:46:18
y paramos, a ver si hemos hecho algo mal 00:46:30
¿eh? 00:46:32
lo que hubiera de antes 00:46:41
Lo borra enterito 00:46:42
No es que sobreescriba 00:46:44
Porque podríamos interpretar que si el de antes tiene algo más 00:46:46
Lo de abajo se queda sin sobreescribir 00:46:49
No, no, no, no, lo limpia todo de cero 00:46:50
Y añade lo que tú 00:46:52
Hayas puesto 00:46:54
¿Eh? 00:46:56
Un segundo abajo 00:46:57
Cada nombre lo va mandando 00:47:00
Vale, pues venga 00:47:07
Aquí me está pidiendo los nombres 00:47:12
Los 10 nombres que yo le he puesto 00:47:14
Vale, ¿en qué fichero 00:47:16
Quiere guardarlo? 00:47:23
Le voy a dar un nombre cualquiera 00:47:25
Porque si no existe, lo va a crear 00:47:27
¿Y dónde? 00:47:28
Como no le hemos dado ruta en la raíz del proyecto 00:47:30
Pues en el fichero 00:47:33
Nombres.txt 00:47:35
Por ejemplo 00:47:37
Terminado 00:47:38
Vale, no ha salido de exception 00:47:40
Entonces si refrescamos aquí el proyecto 00:47:42
Si lo refrescamos 00:47:45
Pues aquí ha aparecido 00:47:48
Y aquí están los nombres 00:47:49
¿Vale? 00:47:52
Como lo he abierto 00:47:57
Si lo haces a refrescar para que te aparezca todo 00:47:58
Claro, yo no he puesto saltos de línea 00:48:00
Entre ellos, pues los ha puesto todos seguidos 00:48:03
Esto, claro, habría sido 00:48:04
Más bonito 00:48:07
Porque así nos ha quedado muy feo 00:48:07
Lógicamente 00:48:10
Habiendo escrito 00:48:12
Write más 00:48:15
El barra n 00:48:16
Claro 00:48:20
Le voy a quitar para que no añade 00:48:25
Y me lo haga de limpias otra vez 00:48:27
Vale, ahora ya me los va a poner 00:48:29
Con salto de línea 00:48:35
Nombres.txt 00:48:36
Por ejemplo 00:48:46
Ahora ya sí 00:48:47
Vale, vamos a parar aquí un segundinín 00:48:52
Materias:
Programación
Niveles educativos:
▼ Mostrar / ocultar niveles
  • Formación Profesional
    • Ciclo formativo de grado superior
      • Primer Curso
Subido por:
Raquel G.
Licencia:
Todos los derechos reservados
Visualizaciones:
4
Fecha:
17 de marzo de 2026 - 12:27
Visibilidad:
Clave
Centro:
IES ROSA CHACEL
Duración:
48′ 59″
Relación de aspecto:
1.78:1
Resolución:
1920x1080 píxeles
Tamaño:
945.12 MBytes

Del mismo autor…

Ver más del mismo autor


EducaMadrid, Plataforma Educativa de la Comunidad de Madrid

Plataforma Educativa EducaMadrid