0Pricing
Lua Academy · Lección

Cierre de archivos y gestión de errores

Cierre correctamente los identificadores de archivo y gestione los errores de io con pcall.

Cierre de archivos y gestión de errores es una lección gratuita de Lua Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Lua Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Lua Academy incluye 4 lecciones en total.

Cerrar siempre los archivos

Todo archivo abierto con io.open debe cerrarse con f:close(). Los archivos que quedan abiertos provocan fugas de descriptores de archivo. El recolector de basura de Lua acabará cerrándolos, pero puede agotar los límites de archivos del sistema operativo antes de que se ejecute el recolector. Cierre siempre el archivo en la función que lo abrió.

local function readFile(path)
  local f, err = io.open(path, "r")
  if not f then return nil, err end
  local content = f:read("a")
  f:close()   -- always close
  return content
end

local data, err = readFile("config.txt")
if not data then print("Error:", err) end

pcall para la seguridad de la E/S

Envuelva las operaciones de archivo en pcall para capturar errores inesperados (disco lleno, permisos denegados durante una escritura). Así podrá gestionar los errores correctamente en lugar de hacer que el programa se bloquee.

local function safeCopy(src, dst)
  local ok, err = pcall(function()
    local f = io.open(src, "rb")
    if not f then error("Cannot open source: " .. src) end
    local content = f:read("a")
    f:close()
    local g = io.open(dst, "wb")
    if not g then error("Cannot open dest: " .. dst) end
    g:write(content)
    g:close()
  end)
  return ok, err
end

local ok, msg = safeCopy("input.txt", "output.txt")
if not ok then print("Failed:", msg) end

Comprobar que la escritura tenga éxito

En sistemas con el disco lleno o con problemas de permisos, f:write() puede fallar incluso después de que io.open haya tenido éxito. Compruebe el valor devuelto por las operaciones de escritura en las rutas críticas.

local f = io.open("important.txt", "w")
if not f then
  print("Cannot create file")
  return
end

local ok, err = f:write("critical data\n")
if not ok then
  print("Write failed:", err)
  f:close()
  return
end

f:close()
print("Saved successfully")

Patrón finally con pcall

Lua no tiene un bloque finally, pero puede simularlo con pcall. Envuelva el código de riesgo en pcall; después de que pcall devuelva el resultado (tanto si tiene éxito como si falla), ejecute siempre el código de limpieza antes de volver a lanzar o gestionar el error.

local function withFile(path, mode, fn)
  local f, err = io.open(path, mode)
  if not f then return nil, err end
  local ok, result = pcall(fn, f)
  f:close()   -- always close, even on error
  if not ok then
    return nil, result
  end
  return result
end

local content, err = withFile("data.txt", "r", function(f)
  return f:read("a")
end)
print(content or err)

Mensajes de error de io.open

io.open devuelve nil junto con un mensaje de error del sistema y un código de error. El mensaje incluye la ruta y el motivo del error del sistema operativo ("No such file", "Permission denied", etc.). Incluya siempre el mensaje de error en el informe que muestre al usuario.

local paths = {"config.txt", "missing.txt", "/root/secret.txt"}

for _, path in ipairs(paths) do
  local f, err, code = io.open(path, "r")
  if f then
    print(path, "-> ok, size:", f:seek("end"))
    f:close()
  else
    print(path, "-> ERROR:", err, "(code "..tostring(code)..")")
  end
end

El handle de archivo como objeto

Un handle de archivo de Lua es un userdata con métodos. Cuando el recolector de basura libera el handle, el archivo se cierra automáticamente. Sin embargo, no dependa del recolector para cerrarlo a tiempo: ciérrelo siempre explícitamente. Puede comprobar si un archivo está cerrado con f:read(); esta operación produce un error si el handle está cerrado.

local f = io.open("test.txt", "w")
f:write("test\n")

-- Explicit close
f:close()

-- After close, operations fail
local ok, err = pcall(function()
  f:read()   -- attempt to use closed file
end)
print(ok, err)   -- false  [closed file]

Plantilla para procesar archivos de forma segura

Una plantilla reutilizable para procesar archivos de forma segura: abrir y comprobar errores, procesar con pcall y cerrar en todos los casos. Devuelva los resultados y los errores de forma coherente mediante la convención nil+message.

local function processFile(path, processor)
  local f, err = io.open(path, "r")
  if not f then return nil, "open failed: " .. err end
  
  local ok, result = pcall(processor, f)
  f:close()
  
  if not ok then
    return nil, "processing failed: " .. result
  end
  return result
end

local lineCount, err = processFile("data.txt", function(f)
  local n = 0
  for _ in f:lines() do n = n + 1 end
  return n
end)
print(lineCount or err)

os.remove y os.rename

os.remove(path) elimina un archivo. os.rename(old, new) cambia el nombre de un archivo o lo mueve. Ambas funciones devuelven true si tienen éxito o nil, errMessage si fallan. Estas son las principales funciones de manipulación del sistema de archivos en el Lua estándar.

-- Delete a file
local ok, err = os.remove("temp.txt")
if not ok then print("Remove failed:", err) end

-- Rename / move
ok, err = os.rename("old_name.txt", "new_name.txt")
if not ok then print("Rename failed:", err) end

-- Atomic update pattern
os.rename("config.new", "config.txt")

io.close frente a f:close

io.close(f) equivale a f:close(). io.close() sin argumentos cierra el archivo de salida predeterminado. En la mayoría del código, use f:close() por claridad.

local f = io.open("test.txt", "w")
f:write("hello\n")

-- Both are equivalent:
-- f:close()
io.close(f)

-- io.close() with no arg closes default output
io.output("out.txt")
io.write("to file\n")
io.close()   -- closes out.txt, restores stdout

Copiar archivos de forma robusta

Una copia de archivos de calidad apta para producción, con gestión de errores en cada paso: abrir el origen, abrir el destino, copiar en bloques, gestionar los errores de escritura y cerrar ambos archivos.

local function copyFile(src, dst, chunkSize)
  chunkSize = chunkSize or 65536
  local fsrc, err1 = io.open(src, "rb")
  if not fsrc then return nil, err1 end
  local fdst, err2 = io.open(dst, "wb")
  if not fdst then fsrc:close(); return nil, err2 end
  
  local ok = true
  local chunk = fsrc:read(chunkSize)
  while chunk and ok do
    local w, werr = fdst:write(chunk)
    if not w then ok = false; err2 = werr end
    chunk = fsrc:read(chunkSize)
  end
  fsrc:close(); fdst:close()
  if not ok then os.remove(dst); return nil, err2 end
  return true
end

Comprobación rápida

¿Cuál es la mejor manera de garantizar que un archivo se cierre siempre en Lua, incluso si se produce un error?

Resumen: cierre y gestión de errores

Resumen:

  • Llame siempre explícitamente a f:close(); no dependa del recolector de basura
  • Envuelva la E/S en pcall para gestionar los errores de forma robusta
  • Use la plantilla "open → pcall → close"
  • os.remove / os.rename para las operaciones del sistema de archivos
  • Compruebe los valores devueltos por las escrituras en el código crítico

Preguntas frecuentes

¿La lección «Cierre de archivos y gestión de errores» es gratis?

Sí — el texto completo de «Cierre de archivos y gestión de errores» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Lua Academy, actualiza a CoddyKit PRO. El curso de Lua Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Cierre de archivos y gestión de errores»?

Cierre correctamente los identificadores de archivo y gestione los errores de io con pcall. Practicas Lua Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Lua Academy?

No se requiere experiencia previa. Lua Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.

¿Cuánto tiempo toma la lección «Cierre de archivos y gestión de errores»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Lua Academy?

Sí. Cada lección de Lua Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Apertura de archivos con io.open
  2. Lectura del contenido de archivos
  3. Escritura y adición en archivos
  4. Cierre de archivos y gestión de errores
← Volver a Lua Academy