Scala: scrive una stringa in un file in una dichiarazione

Per leggere i file in Scala, c’è

Source.fromFile("file.txt").mkString 

Esiste un modo equivalente e conciso per scrivere una stringa su file?

La maggior parte delle lingue supporta qualcosa del genere. Il mio preferito è Groovy:

 def f = new File("file.txt") // Read def s = f.text // Write f.text = "file contents" 

Mi piacerebbe usare il codice per programmi che vanno da una singola riga a una piccola pagina di codice. Dover usare la tua biblioteca non ha senso qui. Mi aspetto che un linguaggio moderno mi permetta di scrivere qualcosa su un file convenientemente.

Ci sono post simili a questo, ma non rispondono alla mia domanda esatta o sono focalizzati su versioni precedenti di Scala.

Per esempio:

  • Leggi l’intero file in Scala?
  • Come scrivere su un file in Scala?

Una linea concisa:

 import java.io.PrintWriter new PrintWriter("filename") { write("file contents"); close } 

È strano che nessuno abbia suggerito operazioni NIO.2 (disponibili da Java 7):

 import java.nio.file.{Paths, Files} import java.nio.charset.StandardCharsets Files.write(Paths.get("file.txt"), "file contents".getBytes(StandardCharsets.UTF_8)) 

Penso che questo sia di gran lunga il modo più semplice, più semplice e più idiomatico, e non ha bisogno di alcuna dipendenza senza Java.

Ecco un one-liner conciso usando la libreria del compilatore Scala:

 scala.tools.nsc.io.File("filename").writeAll("hello world") 

In alternativa, se vuoi usare le librerie Java puoi fare questo hack:

 Some(new PrintWriter("filename")).foreach{p => p.write("hello world"); p.close} 

Se ti piace la syntax di Groovy, puoi usare il modello di progettazione di Pimp-My-Library per portarlo su Scala:

 import java.io._ import scala.io._ class RichFile( file: File ) { def text = Source.fromFile( file )(Codec.UTF8).mkString def text_=( s: String ) { val out = new PrintWriter( file , "UTF-8") try{ out.print( s ) } finally{ out.close } } } object RichFile { implicit def enrichFile( file: File ) = new RichFile( file ) } 

Funzionerà come previsto:

 scala> import RichFile.enrichFile import RichFile.enrichFile scala> val f = new File("/tmp/example.txt") f: java.io.File = /tmp/example.txt scala> f.text = "hello world" scala> f.text res1: String = "hello world 
 import sys.process._ "echo hello world" #> new java.io.File("/tmp/example.txt") ! 

Puoi facilmente usare Apache File Utils . Guarda la funzione writeStringToFile . Usiamo questa libreria nei nostri progetti.

Una micro biblioteca che ho scritto: https://github.com/pathikrit/better-files

 file.write("Hi!") 

o

 file << "Hi!" 

Uno ha anche questo formato, che è al tempo stesso conciso e la libreria sottostante è splendidamente scritta (vedi il codice sorgente):

 import scalax.io.Codec import scalax.io.JavaConverters._ implicit val codec = Codec.UTF8 new java.io.File("hi-file.txt").asOutput.write("I'm a hi file! ... Really!") 

Questo è abbastanza conciso, immagino:

 scala> import java.io._ import java.io._ scala> val w = new BufferedWriter(new FileWriter("output.txt")) w: java.io.BufferedWriter = [email protected] scala> w.write("Alice\r\nBob\r\nCharlie\r\n") scala> w.close() 

Puoi farlo con un mix di librerie Java e Scala. Avrai il pieno controllo sulla codifica dei caratteri. Sfortunatamente, le maniglie dei file non verranno chiuse correttamente.

 scala> import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream scala> import java.io.FileOutputStream import java.io.FileOutputStream scala> BasicIO.transferFully(new ByteArrayInputStream("test".getBytes("UTF-8")), new FileOutputStream("test.txt")) 

AGGIORNAMENTO: Da allora ho creato una soluzione più efficace su cui ho elaborato qui: https://stackoverflow.com/a/34277491/501113

Mi ritrovo a lavorare sempre di più nel Foglio di lavoro Scala con l’IDE di Scala per Eclipse (e credo che ci sia qualcosa di equivalente in IntelliJ IDEA). Ad ogni modo, ho bisogno di essere in grado di fare un one-liner per produrre parte del contenuto quando ottengo “L’uscita supera il limite di taglio”. messaggio se sto facendo qualcosa di significativo, specialmente con le collezioni Scala.

Mi sono inventato un one-liner che inserisco nella parte superiore di ogni nuovo Foglio di lavoro Scala per semplificare questo (e quindi non devo fare l’intero esercizio di importazione di librerie esterne per un’esigenza molto semplice). Se sei un pignolo e noti che è tecnicamente due righe, è solo per renderlo più leggibile in questo forum. È una singola riga nel mio foglio di lavoro Scala.

 def printToFile(content: String, location: String = "C:/Users/jtdoe/Desktop/WorkSheet.txt") = Some(new java.io.PrintWriter(location)).foreach{f => try{f.write(content)}finally{f.close}} 

E l’utilizzo è semplicemente:

 printToFile("A fancy test string\ncontaining newlines\nOMG!\n") 

Ciò mi consente di fornire facoltativamente il nome del file se desidero avere file aggiuntivi oltre il valore predefinito (che sovrascrive completamente il file ogni volta che viene chiamato il metodo).

Quindi, il secondo utilizzo è semplicemente:

 printToFile("A fancy test string\ncontaining newlines\nOMG!\n", "C:/Users/jtdoe/Desktop/WorkSheet.txt") 

Godere!

So che non è una linea, ma risolve i problemi di sicurezza per quanto posso dire;

 // This possibly creates a FileWriter, but maybe not val writer = Try(new FileWriter(new File("filename"))) // If it did, we use it to write the data and return it again // If it didn't we skip the map and print the exception and return the original, just in-case it was actually .write() that failed // Then we close the file writer.map(w => {w.write("data"); w}).recoverWith{case e => {e.printStackTrace(); writer}}.map(_.close) 

Se non ti importa della gestione delle eccezioni, puoi scrivere

 writer.map(w => {w.writer("data"); w}).recoverWith{case _ => writer}.map(_.close) 

Attraverso la magia del punto e virgola, puoi creare qualsiasi cosa ti piaccia.

 import java.io.PrintWriter import java.nio.file.Files import java.nio.file.Paths import java.nio.charset.StandardCharsets import java.nio.file.StandardOpenOption val outfile = java.io.File.createTempFile("", "").getPath val outstream = new PrintWriter(Files.newBufferedWriter(Paths.get(outfile) , StandardCharsets.UTF_8 , StandardOpenOption.WRITE)); outstream.println("content"); outstream.flush(); outstream.close()