Fi

File en Elixir

2 ejercicios

Acerca de File

Las funciones para trabajar con archivos las proporciona el módulo File.

Para leer un archivo completo, usa File.read/1. Para escribir en un archivo, usa File.write/2.

El módulo también proporciona funciones de archivo para copiar, eliminar, renombrar, etc. Sus nombres son similares a sus equivalentes en UNIX, por ejemplo:

Todas las funciones mencionadas del módulo File también tienen una variante con ! que lanza un error en lugar de devolver una tupla de error (por ejemplo, File.read!/1). Usa esa variante si no piensas manejar errores como archivos que no existen o falta de permisos.

File.read("does_not_exist")
# => {:error, :enoent}

File.read!("does_not_exist")
# => ** (File.Error) could not read file "does_not_exist": no such file or directory
#        (elixir 1.10.4) lib/file.ex:353: File.read!/1

Archivos y procesos

Cada vez que se escribe en un archivo con File.write/2, se abre un descriptor de archivo y se genera un nuevo proceso de Elixir. Por esta razón, se debe evitar escribir en un archivo dentro de un bucle usando File.write/2.

En su lugar, puedes abrir un archivo con File.open/2. El segundo argumento de File.open/2 es una lista de modos, que te permite especificar si quieres abrir el archivo para lectura o para escritura.

Los modos más usados son:

  • :read - abre para lectura, el archivo debe existir
  • :write - abre para escritura, el archivo se creará si no existe y el contenido existente se sobrescribirá
  • :append - abre para escritura, el archivo se creará si no existe y el contenido existente se conservará

Para ver una lista completa de todos los modos, consulta la documentación de File.open/2.

File.open/2 devuelve el PID de un proceso que maneja el archivo. Para leer y escribir en el archivo, usa funciones del módulo IO y pasa este PID como dispositivo de E/S.

Cuando termines de trabajar con el archivo, ciérralo con File.close/1.

file = File.open!("README.txt", [:write])
# => #PID<0.157.0>

IO.puts(file, "# README")
# => :ok

File.close(file)
# => :ok

Flujo de archivos

Leer un archivo con File.read/1 va a cargar todo el archivo en memoria de una sola vez. Esto puede ser un problema cuando trabajas con archivos realmente grandes. Para manejarlos de forma eficiente, puedes usar File.open/2 y IO.read/2 para leer el archivo línea por línea, o puedes procesarlo como un flujo con File.stream/3. El flujo implementa tanto el protocolo Enumerable como el Collectable, lo que significa que se puede usar tanto para leer como para escribir.

File.stream!("file.txt")
|> Stream.map(&(&1 <> "!"))
|> Stream.into(File.stream!("new_file.txt"))
|> Stream.run()

Rutas

Todas las funciones que trabajan con archivos requieren una ruta de archivo. Las rutas de archivo pueden ser absolutas o relativas al directorio actual. Para manipular rutas, usa funciones del módulo Path. Para lograr compatibilidad entre plataformas, usa Path.join/1 para crear rutas. Elegirá el separador adecuado para la plataforma.

Path.expand(Path.join(["~", "documents", "important.txt"]))
"/home/user/documents/important.txt"
Editar en GitHub El enlace se abre en una ventana o pestaña nueva

Aprende File

La práctica está bloqueada

Desbloquea 1 ejercicio más para practicar File