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:
File.cp/3 - copia un archivo.File.rm/1 - elimina un archivo.File.rename/2 - renombra y/o mueve un archivo.File.mkdir/1 - crea un directorio.File.cwd/0 - obtiene el directorio de trabajo actual.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
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
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()
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"