Saltar al contenido principal

Módulo File

El módulo File lee y escribe ficheros de texto y gestiona carpetas: abrir, leer, escribir, copiar, renombrar y borrar ficheros, y crear y borrar carpetas. En una placa, los ficheros van en su memoria flash (LittleFS) o en una tarjeta SD; en Windows, en dos carpetas del proyecto que hacen de flash y de tarjeta.

use File

Plataformas​

WindowsESP32 / ESP32-S3ESP32-P4ESP32-S31
flash:La carpeta del .jxr: Build\flash en un proyecto del IDELa memoria flash de la placa (LittleFS)IgualIgual
sd:La carpeta sd de al lado: Build\sdLa tarjeta SDIgualIgual
File.setUnit("sd:") sin tarjetaLa aceptaDa errorIgualIgual
La b del modo ("rb", "wb"…)No traduce los saltos de línea, y deja usar seek en cualquier posiciónNo cambia nadaIgualIgual
Un modo que no está en la tablaLa VM se cierraAbre para escribir si lleva w, a o +, y si no, para leerIgualIgual
writeLine acaba la línea con\r\n (\n si el modo lleva b)\r\n\n\n
isEOF()true después de que una lectura intente pasar del finaltrue en cuanto no queda nada por leerIgualIgual

La memoria flash de la placa se llena con los ficheros del proyecto al pulsar Run, y la tarjeta SD se configura en el perfil de la placa: lo cuenta Pantalla, sonido, SD y red.

Run borra lo que el programa guardó en la flash

Cada Run en una placa vuelve a grabar toda su memoria de ficheros con los del proyecto, y lo que tu programa haya escrito en flash: se pierde (también con Upload Program). La tarjeta SD no se toca. Lo cuenta Grabar el firmware y ejecutar.

Rutas y unidades​

Una ruta puede empezar por la unidad, flash: o sd:. Sin unidad, va a la unidad activa, que al empezar el programa es flash: y se cambia con File.setUnit.

use File

var f = File.open("flash:datos.txt", "w") // en la flash
f.close()

var g = File.open("sd:registro.txt", "a") // en la tarjeta SD
g.close()

println(File.exists("datos.txt")) // true: sin unidad, va a la flash
  • Las carpetas se separan con /. Con barra al principio o sin ella, la ruta empieza en la raíz de la unidad: "datos.txt" y "/datos.txt" son el mismo fichero.
  • En una ruta sin unidad, un flash/ o un sd/ al principio se quita: "flash/Images/fondo.bmp" es "Images/fondo.bmp".
  • Los mensajes de error llevan la ruta completa: en Windows, la carpeta entera del disco; en la placa, la ruta desde la raíz, como /datos.txt.

Funciones​

FunciónQué haceDevuelve
File.open(ruta, modo)Abre un ficheroEl fichero abierto
File.exists(ruta)Mira si existe un fichero o una carpetatrue o false
File.delete(ruta)Borra un ficherotrue
File.rename(ruta, nuevaRuta)Cambia el nombre de un fichero o lo mueve, en la misma unidadtrue
File.copy(ruta, destino)Copia un fichero, también de una unidad a otratrue
File.isDir(ruta)Mira si la ruta es una carpetatrue o false
File.mkDir(ruta)Crea una carpetatrue
File.rmDir(ruta)Borra una carpeta vacíatrue
File.size(ruta)El tamaño de un ficheroLos bytes, un entero
File.setUnit(unidad)Cambia la unidad activatrue
File.getUnit()La unidad activa"flash:" o "sd:"

Si algo falla, lanzan una excepción, que se captura con try (ver Errores y excepciones). Además de los errores de cada una, todas menos getUnit dan ERR_INVALID_ARG_NUMBER si no les pasas los argumentos que piden, y ERR_TYPE_MISMATCH si una ruta no es una cadena.

open(ruta, modo)​

Abre el fichero ruta y devuelve el fichero abierto, con los métodos de Objetos que devuelve.

ModoPara qué
"r"Leer. El fichero tiene que existir.
"w"Escribir. Lo crea, o lo vacía si ya existe.
"a"Añadir al final. Lo crea si no existe.
"r+"Leer y escribir. El fichero tiene que existir.
"w+"Leer y escribir. Lo crea, o lo vacía si ya existe.
"a+"Leer y añadir al final.

Cualquiera de ellos puede llevar una b ("rb", "wb", "r+b"…): en Windows, el fichero se lee y se escribe tal cual, sin cambiar los saltos de línea, y seek puede ir a cualquier posición. En las placas, la b no cambia nada.

La carpeta del fichero tiene que existir: File.open no crea carpetas.

ErrorCuándo
ERR_FILE_NOT_FOUNDNo se puede abrir: con "r", el fichero no existe; con "w" o "a", la carpeta no existe. El mensaje dice la ruta y el modo: Could not open file '…' in mode 'r'.
ERR_INVALID_VALUEEl modo no es de la tabla, como "rw" o "x". El mensaje dice el modo.
use File

// Escribir
var f = File.open("salida.txt", "w")
f.writeLine("Hola desde JARU")
f.close()

// Leer
var g = File.open("salida.txt", "r")
println(g.readLine()) // Hola desde JARU
g.close()

exists(ruta)​

Devuelve true si existe un fichero o una carpeta con esa ruta, y false si no.

use File

if (File.exists("config.txt")) then
println("El fichero existe")
else
println("No lo encuentro")
end

delete(ruta)​

Borra el fichero ruta y devuelve true. Si no existe o no se puede borrar, lanza ERR_FILE_NOT_FOUND. Para borrar una carpeta, usa rmDir.

use File

if (File.exists("temporal.txt")) then
File.delete("temporal.txt")
end

rename(ruta, nuevaRuta)​

Cambia el nombre del fichero ruta a nuevaRuta, o lo mueve de carpeta, y devuelve true. Las dos rutas tienen que estar en la misma unidad: para pasar un fichero de la flash a la tarjeta, usa copy y después delete.

ErrorCuándo
ERR_INVALID_VALUELas rutas son de unidades distintas.
ERR_FILE_NOT_FOUNDNo se puede: el fichero no existe, o la carpeta de destino no existe.
use File

File.rename("borrador.txt", "final.txt")

copy(ruta, destino)​

Copia el fichero ruta en destino y devuelve true. Si destino ya existe, lo sustituye. Puede copiar de una unidad a otra.

ErrorCuándo
ERR_FILE_NOT_FOUNDNo se puede abrir el fichero de origen, o no se puede crear el de destino (por ejemplo, porque su carpeta no existe).
ERR_FILE_WRITE_FAILFalla la escritura a medias (por ejemplo, porque la unidad se llena).
use File

File.copy("flash:config.txt", "sd:copias/config.txt") // de la flash a la tarjeta

isDir(ruta)​

Devuelve true si ruta es una carpeta, y false si es un fichero o no existe.

use File

if (!File.isDir("registros")) then
File.mkDir("registros")
end

mkDir(ruta)​

Crea la carpeta ruta y devuelve true. Crea una sola carpeta: la de arriba tiene que existir. Si no se puede crear, lanza ERR_FILE_WRITE_FAIL; en Windows, también si ya existe (con el mensaje Directory '…' already exists.). Mira antes con exists.

use File

if (!File.exists("registros")) then
File.mkDir("registros")
end

rmDir(ruta)​

Borra la carpeta ruta y devuelve true. Tiene que estar vacía: borra antes sus ficheros con delete. Si no está vacía o no existe, lanza ERR_FILE_WRITE_FAIL.

use File

File.rmDir("registros/viejos")

size(ruta)​

Devuelve el tamaño del fichero ruta, en bytes. Si no existe, lanza ERR_FILE_NOT_FOUND.

use File

println("Ocupa ", File.size("datos.txt"), " bytes")

setUnit(unidad)​

Cambia la unidad activa, la que usan las rutas sin unidad: "flash:" o "sd:". Devuelve true.

ErrorCuándo
ERR_INVALID_VALUEunidad no es "flash:" ni "sd:".
ERR_FILE_NOT_FOUNDEn una placa, pides "sd:" y no hay tarjeta montada. En Windows, "sd:" se acepta siempre.
use File

File.setUnit("sd:") // desde aquí, las rutas sin unidad van a la tarjeta
var f = File.open("registro.txt", "a")
f.writeLine("Entrada del registro")
f.close()

File.setUnit("flash:") // y desde aquí, otra vez a la flash

getUnit()​

Devuelve la unidad activa: "flash:" o "sd:".

use File

println(File.getUnit()) // flash:

Objetos que devuelve​

File.open devuelve el fichero abierto. Sus métodos leen y escriben en él desde una posición que avanza con cada lectura o escritura:

MétodoQué haceDevuelve
write(texto)Escribe una cadenaLos caracteres escritos
writeLine(texto)Escribe una cadena y un salto de líneaLos caracteres escritos
read()Lee desde la posición hasta el finalUna cadena
readLine()Lee la línea siguiente, sin el salto de líneaUna cadena, o nil al final
seek(pos) / seek(pos, origen)Mueve la posición0 si lo consigue
position()La posición, en bytes desde el principioUn entero
size()El tamaño del fichero, en bytesUn entero
isEOF()Mira si se ha llegado al finaltrue o false
isOpen()Mira si el fichero sigue abiertotrue o false
close()Cierra el ficheronil

Todos dan ERR_INVALID_ARG_NUMBER si no les pasas los argumentos que piden. Después de close(), todos menos isOpen y close dan error: ERR_FILE_WRITE_FAIL al escribir, ERR_FILE_READ_FAIL al leer y ERR_INVALID_OPERATION en los demás.

write(texto)​

Escribe la cadena texto en el fichero y devuelve cuántos caracteres ha escrito. texto tiene que ser una cadena: para escribir un número, conviértelo antes con toString().

Si el fichero se abrió con "r", lanza ERR_FILE_WRITE_FAIL (File was opened in read-only mode ('r').).

writeLine(texto)​

Como write, y además acaba la línea. En Windows y en ESP32 y ESP32-S3, la línea acaba en \r\n; en el P4 y el S31, en \n. readLine entiende las dos.

use File

var f = File.open("lista.txt", "w")
f.writeLine("primera")
f.writeLine("segunda")
f.close()

read()​

Lee desde la posición hasta el final del fichero y lo devuelve en una cadena. Para leer el fichero entero, llámalo nada más abrirlo, o después de seek(0).

readLine()​

Lee la línea siguiente y la devuelve sin el salto de línea, sea \n o \r\n. Al llegar al final, devuelve nil. La última línea se lee aunque no acabe en salto de línea.

use File

var f = File.open("lista.txt", "r")
var linea = f.readLine()
while (linea != nil)
println(linea)
linea = f.readLine()
end
f.close()

seek(pos, origen)​

Mueve la posición a pos bytes desde el principio, que es lo de serie. Con origen mide desde otro sitio: 0, el principio; 1, la posición de ahora; 2, el final (con un pos negativo para ir hacia atrás). Un origen que no es ninguno de esos cuenta como 0.

Devuelve 0 si lo consigue y otro número si no. pos y origen tienen que ser enteros (ERR_TYPE_MISMATCH).

En Windows, si el modo no lleva b, solo se puede ir a la posición 0: con otra, lanza ERR_INVALID_OPERATION. Abre el fichero con "rb" para ir a cualquier posición.

use File

var f = File.open("lista.txt", "rb")
f.seek(-8, 2) // 8 bytes antes del final
println(f.position())
f.close()

position()​

Devuelve la posición, en bytes desde el principio del fichero.

size()​

Devuelve el tamaño del fichero abierto, en bytes, sin mover la posición. Es lo mismo que File.size con su ruta.

isEOF()​

Devuelve true si se ha llegado al final del fichero.

En Windows se pone a true después de que una lectura intente pasar del final: después de leer la última línea con readLine sigue en false, y pasa a true cuando readLine devuelve nil. En las placas se pone a true en cuanto no queda nada por leer. Para recorrer un fichero, mira lo que devuelve readLine, no isEOF().

isOpen()​

Devuelve true si el fichero está abierto, y false después de close().

close()​

Cierra el fichero y devuelve nil. Lo que hayas escrito queda en el disco o en la flash. Cerrarlo otra vez no hace nada.

Ejemplo completo​

Un registro de eventos: añade líneas con la hora a un fichero, lo lee entero y dice cuánto ocupa.

use File

// La carpeta del registro
if (!File.exists("registros")) then
File.mkDir("registros")
end

func anotar(mensaje)
var f = File.open("registros/registro.txt", "a")
f.writeLine("[" + time() + "] " + mensaje)
f.close()
end

func mostrar()
if (!File.exists("registros/registro.txt")) then
println("Todavía no hay registro")
return
end
var f = File.open("registros/registro.txt", "r")
var linea = f.readLine()
while (linea != nil)
println(linea)
linea = f.readLine()
end
f.close()
end

anotar("Sistema iniciado")
anotar("Sensor activo")
anotar("Temperatura: 23.5 grados")

mostrar()
println("El registro ocupa ", File.size("registros/registro.txt"), " bytes")

La primera vez, en Windows, imprime algo así (la hora es la del momento; time() la da en texto):

[Fri Nov  6 19:44:07 2026] Sistema iniciado
[Fri Nov 6 19:44:07 2026] Sensor activo
[Fri Nov 6 19:44:07 2026] Temperatura: 23.5 grados
El registro ocupa 140 bytes

Cada vez que lo ejecutas, el registro crece: "a" añade al final.

Trampas y problemas conocidos​

  • Solo texto. write y writeLine escriben cadenas, y una cadena se corta en el primer byte 0: el módulo no sirve para escribir datos binarios. read sí devuelve todos los bytes.
  • seek en Windows, con b. Sin la b en el modo, seek solo va a la posición 0.
  • No hay forma de listar una carpeta. El módulo no tiene una función que diga qué ficheros hay: guarda tú los nombres, por ejemplo en un fichero índice.
  • Las carpetas, de una en una. Ni mkDir ni open crean las carpetas de arriba.
  • Cierra los ficheros. Hasta close(), lo escrito puede no estar todavía en la flash o en la tarjeta.

Todos los problemas conocidos de JARU, juntos, están en Problemas conocidos.