Kotlin I/O su file
Output su file
Per creare file in Kotlin, abbiamo più "metodi", usando praticamente gli stessi oggetti di Java.
Vediamo alcuni esempi usando:
File.writeText()
File.bufferedWriter()
File.printWriter()
PrintWriter
In alcuni casi useremo il metodo use{}, per fare in modo che il blocco di codice si auto-chiuda e liberi risorse automaticamente (chiusa il file e liberi tutte le risorse del buffer), anche nel caso di eventuali eccezioni. Invece nel primo caso la chiusura del file viene fatta in maniera implicita, come la liberazione delle risorse. Vediamo alcuni modi:
- Utilizzare il metodo writeText() della classe File:
File("wt.txt").writeText("CIAO MONDO!")
- Oppure utilizzare il metodo bufferedWriter(), sempre della classe File, insieme ad use{}:
File("buff.txt").bufferedWriter().use {
out -> {
out.write("CIAO MONDO!")
out.newLine()
}
}
- Oppure utilizzare il metodo printWirter(), sempre della classe File, insieme ad use{}:
File("print.txt").printWriter().use {
out -> out.println("CIAO MONDO!")
}
File("print.txt").printWriter().use {
out -> {
out.print("CIAO ")
out.println("MONDO!")
}
}
- Inoltre se la classe File è troppo brutta è sempre possibile usare la classe PrintWriter:
PrintWriter("file.txt").use {
out -> out.println("CIAO MONDO!")
}
Il risultato sarà sempre lo stesso in tutti questi esempi. In alcuni è possibile eseguire più istruzioni, in writeText() è possibile scrivere solo una stringa. La variabile out è un po' strana, infatti essa è una espressione Lambda, che vedremo in futuro.
Input da file
Per leggre un file in Kotlin, abbiamo diverse modalità, tutte con pochissime righe di codice.
Vi mostro tre modi:
- Nel primo usiamo direttamente il metodo forEachLine{} della classe File:
File("file.txt").forEachLine { println(in) }
- Quell'in è un parametro con nome implicito; in pratica accorcia ulteriormente la sintassi della lambda expression nel caso di un parametro.
- Il secondo esempio il metodo readLines(), ed è molto simile al primo:
val lines = File("test.txt").readLines()
lines.forEach { println(in) }
- Infine, possiamo usare readText(), che però legge il file tutto insieme e non riga per riga:
val text = File("test.txt").readText()
println(text)
Quale dei metodi usare dipende da cosa vogliamo fare con il file. Ricordo inoltre che è sempre possibile trasformare le stringe in interi, double:
fun readInts(text: String, separator: Char = ' ') = readLine()!!.split(separator).map(String::toInt)
fun main(args: Array<String>) {
val text = File("test.txt").readText()
val ints = readInts(text)
for(int in ints) {
println(int)
}
}