Fi

File in Elixir

2 esercizi

Informazioni su File

Le funzioni per lavorare con i file sono fornite dal modulo File.

Per leggere un intero file, usa File.read/1. Per scrivere su un file, usa File.write/2.

Il modulo fornisce anche funzioni per copiare, rimuovere, rinominare i file e così via. I loro nomi sono simili a quelli delle equivalenti UNIX, per esempio:

Tutte le funzioni menzionate del modulo File hanno anche una variante con ! che solleva un errore invece di restituire una tupla di errore (ad esempio File.read!/1). Usa quella variante se non hai intenzione di gestire errori come file mancanti o permessi insufficienti.

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

File e processi

Ogni volta che si scrive su un file con File.write/2, viene aperto un descrittore di file e viene generato un nuovo processo Elixir. Per questo motivo, conviene evitare di scrivere su un file in un ciclo usando File.write/2.

Invece, un file può essere aperto usando File.open/2. Il secondo argomento di File.open/2 è un array di modalità, che ti permette di specificare se vuoi aprire il file in lettura o in scrittura.

Le modalità più usate sono:

  • :read: apre in lettura, il file deve esistere
  • :write: apre in scrittura, il file viene creato se non esiste, il contenuto esistente viene sovrascritto
  • :append: apre in scrittura, il file viene creato se non esiste, il contenuto esistente viene conservato

Per conoscere tutte le modalità disponibili, consulta la documentazione di File.open/2.

File.open/2 restituisce il PID di un processo che gestisce il file. Per leggere e scrivere sul file, usa le funzioni del modulo IO e passa questo PID come dispositivo IO.

Quando hai finito di lavorare con il file, chiudilo con File.close/1.

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

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

File.close(file)
# => :ok

Streaming dei file

Leggere un file con File.read/1 carica l'intero file in memoria tutto in una volta. Questo può essere un problema quando si lavora con file davvero grandi. Per gestirli in modo efficiente, puoi usare File.open/2 e IO.read/2 per leggere il file riga per riga, oppure puoi ricorrere allo streaming con File.stream/3. Lo stream implementa sia il protocollo Enumerable sia il Collectable, quindi può essere usato sia per leggere sia per scrivere.

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

Percorsi

Tutte le funzioni che lavorano sui file richiedono un percorso di file. I percorsi possono essere assoluti o relativi alla directory corrente. Per manipolare i percorsi, usa le funzioni del modulo Path. Per garantire la compatibilità tra piattaforme, usa Path.join/1 per costruire i percorsi: sceglierà il separatore adatto alla piattaforma.

Path.expand(Path.join(["~", "documents", "important.txt"]))
"/home/user/documents/important.txt"
Modifica tramite GitHub Il collegamento si apre in una nuova finestra o scheda

Impara File

La pratica è bloccata

Sblocca un altro esercizio per esercitarti su File