Zum Lesen von Dateien in Scala gibt es
Source.fromFile("file.txt").mkString
Gibt es eine äquivalente und präzise Möglichkeit, eine Zeichenfolge in eine Datei zu schreiben?
Die meisten Sprachen unterstützen so etwas. Mein Favorit ist Groovy:
def f = new File("file.txt")
// Read
def s = f.text
// Write
f.text = "file contents"
Ich möchte den Code für Programme verwenden, die von einer einzelnen Zeile bis zu einer kurzen Codeseite reichen. Die Nutzung einer eigenen Bibliothek ist hier nicht sinnvoll. Ich erwarte von einer modernen Sprache, dass ich bequem etwas in eine Datei schreiben kann.
Es gibt ähnliche Posts, die jedoch nicht meine genaue Frage beantworten oder sich auf ältere Scala Versionen konzentrieren.
Beispielsweise:
Eine kurze Zeile:
import Java.io.PrintWriter
new PrintWriter("filename") { write("file contents"); close }
Es ist seltsam, dass niemand NIO.2-Operationen vorgeschlagen hatte (verfügbar seit 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))
Ich denke, dies ist bei weitem der einfachste, einfachste und idiomatischste Weg, und es sind keine Abhängigkeiten ohne Java selbst erforderlich.
Hier ist ein kompakter Einzeiler, der reflect.io.file verwendet. Dies funktioniert mit Scala 2.12:
reflect.io.File("filename").writeAll("hello world")
Wenn Sie alternativ die Bibliotheken Java verwenden möchten, können Sie diesen Hack ausführen:
Some(new PrintWriter("filename")).foreach{p => p.write("hello world"); p.close}
Wenn Sie die Groovy-Syntax mögen, können Sie das Entwurfsmuster Pimp-My-Library für Scala verwenden:
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 )
}
Es wird wie erwartet funktionieren:
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") !
Sie können einfach Apache File Utils verwenden. Schauen Sie sich die Funktion writeStringToFile
an. Wir verwenden diese Bibliothek in unseren Projekten.
Eine Mikrobibliothek, die ich geschrieben habe: https://github.com/pathikrit/better-files
file.write("Hi!")
oder
file << "Hi!"
Das ist prägnant genug, denke ich:
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()
Man hat auch dieses Format, das sowohl prägnant als auch die zugrunde liegende Bibliothek schön geschrieben ist (siehe den Quellcode):
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!")
Ich weiß, es ist keine einzige Zeile, aber sie löst die Sicherheitsprobleme, soweit ich das beurteilen kann.
// 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)
Wenn Sie sich nicht um die Ausnahmebehandlung gekümmert haben, können Sie schreiben
writer.map(w => {w.writer("data"); w}).recoverWith{case _ => writer}.map(_.close)
Sie können dies mit einer Mischung aus Java und Scala) - Bibliotheken tun. Sie haben die volle Kontrolle über die Zeichenkodierung. Leider werden die Datei-Handles nicht richtig geschlossen.
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"))
UPDATE: Ich habe seitdem eine effektivere Lösung erstellt, auf die ich hier näher eingegangen bin: https://stackoverflow.com/a/34277491/50111
Ich stelle fest, dass ich immer mehr im Arbeitsblatt Scala in Scala IDE für Eclipse arbeite (und ich glaube, dass es in IntelliJ IDEA etwas Äquivalentes gibt). Wie auch immer, ich muss in der Lage sein, einen Einzeiler zu erstellen, um einen Teil des Inhalts auszugeben, wenn die Meldung "Ausgabe überschreitet Grenzwert" angezeigt wird. Nachricht, wenn ich etwas Wichtiges tue, besonders mit den Scala Sammlungen.
Ich habe mir einen Einzeiler ausgedacht, den ich oben in jedes neue Scala Arbeitsblatt eingefügt habe, um dies zu vereinfachen (und daher muss ich nicht die gesamte Übung zum Importieren externer Bibliotheken ausführen, um eine sehr einfache Anforderung zu erfüllen). Wenn Sie ein Stickler sind und feststellen, dass es sich technisch gesehen um zwei Zeilen handelt, dient dies nur dazu, die Lesbarkeit in diesem Forum zu verbessern. Es ist eine einzelne Zeile in meinem Arbeitsblatt 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}}
Und die Verwendung ist einfach:
printToFile("A fancy test string\ncontaining newlines\nOMG!\n")
Auf diese Weise kann ich optional den Dateinamen angeben, falls ich über den Standard hinaus zusätzliche Dateien haben möchte (wodurch die Datei bei jedem Aufruf der Methode vollständig überschrieben wird).
Die zweite Verwendung ist also einfach:
printToFile("A fancy test string\ncontaining newlines\nOMG!\n", "C:/Users/jtdoe/Desktop/WorkSheet.txt")
Genießen!
Durch die Magie des Semikolons können Sie alles, was Sie mögen, zu einem Einzeiler machen.
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()