web-dev-qa-db-fra.com

Scala: écrit une chaîne dans un fichier en une seule déclaration

Pour lire des fichiers en Scala, il y a

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

Existe-t-il un moyen équivalent et concis d'écrire une chaîne dans un fichier?

La plupart des langues supportent quelque chose comme ça. Mon préféré est Groovy:

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

J'aimerais utiliser le code pour des programmes allant d'une simple ligne à une courte page de code. Devoir utiliser sa propre bibliothèque n'a pas de sens ici. Je m'attends à ce qu'un langage moderne me laisse écrire facilement quelque chose dans un fichier.

Il existe des publications similaires, mais elles ne répondent pas à ma question exacte ou sont centrées sur des versions plus anciennes Scala.

Par exemple:

134
smartnut007

Une ligne concise:

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

Il est étrange que personne n’ait suggéré d’opérations NIO.2 (disponible depuis 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))

Je pense que c’est de loin le moyen le plus simple, le plus simple et le plus idiomatique, et il n’a pas besoin de dépendances sans Java lui-même.

152
Vladimir Matveev

Voici un one-liner concis utilisant reflect.io.file, cela fonctionne avec Scala 2.12:

reflect.io.File("filename").writeAll("hello world")

Sinon, si vous voulez utiliser les bibliothèques Java vous pouvez faire ceci:

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

Si vous aimez la syntaxe Groovy, vous pouvez utiliser le modèle de conception Pimp-My-Library pour l’apporter à 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 )

}

Cela fonctionnera comme prévu:

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
40
paradigmatic
import sys.process._
"echo hello world" #> new Java.io.File("/tmp/example.txt") !
22
xiefei

Vous pouvez facilement utiliser Apache File Utils . Regardez la fonction writeStringToFile. Nous utilisons cette bibliothèque dans nos projets.

12
RyuuGan

Une micro bibliothèque j'ai écrit: https://github.com/pathikrit/better-files

file.write("Hi!")

ou

file << "Hi!"
12
pathikrit

Ceci est assez concis, je suppose:

scala> import Java.io._
import Java.io._

scala> val w = new BufferedWriter(new FileWriter("output.txt"))
w: Java.io.BufferedWriter = Java.io.BufferedWriter@44ba4f

scala> w.write("Alice\r\nBob\r\nCharlie\r\n")

scala> w.close()
7
Luigi Sgro

On a aussi ce format, qui est à la fois concis et la bibliothèque sous-jacente joliment écrite (voir le code source):

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!")
6
Dibbeke

Je sais que ce n'est pas une ligne, mais cela résout les problèmes de sécurité autant que je sache;

// 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)

Si vous ne vous souciez pas de la gestion des exceptions, vous pouvez écrire

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

Vous pouvez le faire avec un mélange de bibliothèques Java et Scala. Vous aurez un contrôle total sur l'encodage des caractères. Mais malheureusement, les descripteurs de fichiers ne seront pas fermés correctement.

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"))
2
stefan.schwetschke

MISE À JOUR: J'ai depuis créé une solution plus efficace sur laquelle j'ai développé ici: https://stackoverflow.com/a/34277491/50111

Je me retrouve de plus en plus à travailler dans la feuille de travail Scala au sein de la Scala IDE pour Eclipse (et je pense qu'il existe quelque chose d'équivalent dans IntelliJ IDEA). Quoi qu'il en soit, je dois être capable de faire une ligne pour sortir une partie du contenu lorsque je reçois le message "La sortie dépasse la limite de coupure". message si je fais quelque chose d'important, en particulier avec les collections Scala.

Pour simplifier cela, j’ai créé une ligne que j’ai insérée dans le haut de chaque nouvelle feuille de calcul Scala (et je n’ai donc pas besoin de faire l’ensemble de l’exercice d’importation de bibliothèque externe pour un besoin très simple). Si vous êtes un stickler et que vous remarquez qu'il s'agit techniquement de deux lignes, c'est uniquement pour le rendre plus lisible dans ce forum. C'est une seule ligne dans ma feuille de travail 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}}

Et l'utilisation est simplement:

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

Cela me permet de fournir éventuellement le nom du fichier si je veux avoir des fichiers supplémentaires au-delà du fichier par défaut (qui écrase complètement le fichier à chaque appel de la méthode).

Donc, la deuxième utilisation est simplement:

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

Prendre plaisir!

1
chaotic3quilibrium

Grâce à la magie du point-virgule, vous pouvez faire ce que vous voulez comme une ligne.

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()
0
Ion Freeman