158 votes

Comment écrire dans un fichier en Scala ?

Pour la lecture, il y a l'abstraction utile Source . Comment puis-je écrire des lignes dans un fichier texte ?

1 votes

Si vous savez comment faire en Java, vous pouvez faire de même en Scala. Votre question concerne-t-elle spécifiquement la bibliothèque standard de Scala ?

1 votes

@wheaties oui la meilleure façon de faire cela en scala

0 votes

Cette bibliothèque est vraiment bien : github.com/pathikrit/better-files

212voto

Rex Kerr Points 94401

C'est l'une des fonctionnalités manquantes de Scala standard que j'ai trouvée si utile que je l'ai ajoutée à ma bibliothèque personnelle. (Vous devriez probablement avoir une bibliothèque personnelle, vous aussi.) Le code se présente comme suit :

def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) {
  val p = new java.io.PrintWriter(f)
  try { op(p) } finally { p.close() }
}

et c'est utilisé comme ça :

import java.io._
val data = Array("Five","strings","in","a","file!")
printToFile(new File("example.txt")) { p =>
  data.foreach(p.println)
}

1 votes

La nouvelle fonction java.io.PrintWriter() utilise l'encodage par défaut de la plate-forme, ce qui signifie probablement que le fichier résultat n'est pas très portable. Par exemple, si vous souhaitez produire un fichier que vous pourrez ensuite envoyer par e-mail, vous devriez probablement utiliser le constructeur PrintWriter qui vous permet de spécifier un encodage.

0 votes

@JonaChristopherSahnwaldt - Bien sûr, dans des cas particuliers, vous pourriez vouloir spécifier l'encodage. La valeur par défaut de la plateforme est la plus judicieuse en moyenne. Comme pour Source (encodage par défaut). Vous pouvez bien sûr ajouter par exemple un enc: Option[String] = None paramètre après f si vous trouvez que c'est un besoin commun.

6 votes

@RexKerr - Je ne suis pas d'accord. Il faut spécifier l'encodage dans presque tous les cas. La plupart des erreurs d'encodage que je rencontre se produisent parce que les gens ne comprennent pas ou ne pensent pas à l'encodage. Ils utilisent la valeur par défaut et ne le savent même pas, car trop d'API les laissent s'en tirer à bon compte. De nos jours, la valeur par défaut la plus raisonnable serait probablement UTF-8. Peut-être travaillez-vous uniquement avec l'anglais et d'autres langues qui peuvent être écrites en ASCII. Vous avez de la chance. Je vis en Allemagne et j'ai dû réparer plus de trémas cassés que je ne peux m'en souvenir.

73voto

VonC Points 414372

Édition 2019 (8 ans plus tard), Scala-IO n'étant pas très actif, le cas échéant, Li Haoyi propose sa propre bibliothèque lihaoyi/os-lib qu'il présente ci-dessous .

Juin 2019, Xavier Guihot mentions dans sa réponse la bibliothèque Using un utilitaire pour effectuer une gestion automatique des ressources.


Edit (septembre 2011) : depuis Eduardo Costa pose des questions sur Scala2.9, et puisque Rick-777 commentaires que scalax.IO historique des livraisons est à peu près inexistant depuis la mi-2009...

Scala-IO a changé de place : voir son Repo GitHub , de Jesse Eichar (également sur le SO ) :

Le projet Scala IO est composé de plusieurs sous-projets portant sur différents aspects et extensions de l'IO.
Il existe deux composants principaux de Scala IO :

  • Core - Core traite principalement de la lecture et de l'écriture de données vers et depuis des sources et des puits arbitraires. Les traits de base sont Input , Output y Seekable qui fournissent l'API de base.
    Les autres classes d'importance sont Resource , ReadChars y WriteChars .
  • Fichier - Le fichier est un File (appelé Path ) qui est basée sur une combinaison du système de fichiers Java 7 NIO et des API SBT PathFinder.
    Path y FileSystem sont les principaux points d'entrée dans l'API Scala IO File.
import scalax.io._

val output:Output = Resource.fromFile("someFile")

// Note: each write will open a new connection to file and 
//       each write is executed at the begining of the file,
//       so in this case the last write will be the contents of the file.
// See Seekable for append and patching files
// Also See openOutput for performing several writes with a single connection

output.writeIntsAsBytes(1,2,3)
output.write("hello")(Codec.UTF8)
output.writeStrings(List("hello","world")," ")(Codec.UTF8)

Réponse originale (janvier 2011), avec l'ancien emplacement de scala-io :

Si vous ne voulez pas attendre Scala2.9, vous pouvez utiliser la fonction scala-incubateur / scala-io bibliothèque.
(comme mentionné dans " Pourquoi Scala Source ne ferme-t-il pas l'InputStream sous-jacent ? ")

Ver les échantillons

{ // several examples of writing data
    import scalax.io.{
      FileOps, Path, Codec, OpenOption}
    // the codec must be defined either as a parameter of ops methods or as an implicit
    implicit val codec = scalax.io.Codec.UTF8

    val file: FileOps = Path ("file")

    // write bytes
    // By default the file write will replace
    // an existing file with the new data
    file.write (Array (1,2,3) map ( _.toByte))

    // another option for write is openOptions which allows the caller
    // to specify in detail how the write should take place
    // the openOptions parameter takes a collections of OpenOptions objects
    // which are filesystem specific in general but the standard options
    // are defined in the OpenOption object
    // in addition to the definition common collections are also defined
    // WriteAppend for example is a List(Create, Append, Write)
    file.write (List (1,2,3) map (_.toByte))

    // write a string to the file
    file.write("Hello my dear file")

    // with all options (these are the default options explicitely declared)
    file.write("Hello my dear file")(codec = Codec.UTF8)

    // Convert several strings to the file
    // same options apply as for write
    file.writeStrings( "It costs" :: "one" :: "dollar" :: Nil)

    // Now all options
    file.writeStrings("It costs" :: "one" :: "dollar" :: Nil,
                    separator="||\n||")(codec = Codec.UTF8)
  }

17 votes

Et une version de Scala 2.9 :)

0 votes

Le projet scalax semble mort (pas de commits depuis juin 2009). Est-ce exact ? Historique des livraisons de scalax

0 votes

@Eduardo : J'ai complété ma réponse avec le nouvel emplacement de la bibliothèque scala-io (qui a été mise à jour pour Scala2.9 : github.com/jesseeichar/scala-io/issues/20 )

51voto

Jus12 Points 4580

Similaire à la réponse de Rex Kerr, mais plus générique. J'utilise d'abord une fonction d'aide :

/**
 * Used for reading/writing to database, files, etc.
 * Code From the book "Beginning Scala"
 * http://www.amazon.com/Beginning-Scala-David-Pollak/dp/1430219890
 */
def using[A <: {def close(): Unit}, B](param: A)(f: A => B): B =
try { f(param) } finally { param.close() }

Alors je l'utilise comme :

def writeToFile(fileName:String, data:String) = 
  using (new FileWriter(fileName)) {
    fileWriter => fileWriter.write(data)
  }

et

def appendToFile(fileName:String, textData:String) =
  using (new FileWriter(fileName, true)){ 
    fileWriter => using (new PrintWriter(fileWriter)) {
      printWriter => printWriter.println(textData)
    }
  }

etc.

40 votes

Ne vous méprenez pas, j'aime votre code et il est très éducatif, mais plus je vois de telles constructions pour des problèmes simples, plus cela me rappelle la vieille blague "hello world" : ariel.com.au/jokes/The_Evolution_of_a_Programmer.html :-) (+1 vote de ma part).

4 votes

Si vous écrivez des one-liners, rien ne compte. Si vous écrivez des programmes importants (de grande taille avec un besoin permanent de maintenance et d'évolution), ce type de raisonnement conduit à la dégradation la plus rapide et la plus pernicieuse de la qualité des logiciels.

3 votes

Tout le monde n'aura pas les "yeux de Scala" avant un certain niveau de pratique. Il est amusant de voir que cet exemple de code provient d'un Scala "débutant".

38voto

samthebest Points 2097

Une réponse simple :

import java.io.File
import java.io.PrintWriter

def writeToFile(p: String, s: String): Unit = {
    val pw = new PrintWriter(new File(p))
    try pw.write(s) finally pw.close()
  }

1 votes

@samthebest pourriez vous ajouter les bibliothèques que vous import de ?

1 votes

A partir de java 7, utilisez plutôt java.nio.file : def writeToFile(file : String, stringToWrite : String) : Unit = { val writer = Files.newBufferedWriter(Paths.get(file)) try writer.write(stringToWrite) finally writer.close() }

18voto

samthebest Points 2097

Je donne une autre réponse, car mes modifications des autres réponses ont été rejetées.

C'est le la réponse la plus concise et la plus simple (similaire à celui de Garret Hall)

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

Cette méthode est similaire à celle de Jus12, mais sans la verbosité et avec une correction style de code

def using[A <: {def close(): Unit}, B](resource: A)(f: A => B): B =
  try f(resource) finally resource.close()

def writeToFile(path: String, data: String): Unit = 
  using(new FileWriter(path))(_.write(data))

def appendToFile(path: String, data: String): Unit =
  using(new PrintWriter(new FileWriter(path, true)))(_.println(data))

Notez que vous n'avez PAS besoin des accolades pour try finally ni les lambdas, et notez l'utilisation de la syntaxe des caractères de remplacement. Notez également l'amélioration des noms.

2 votes

Désolé, mais votre code est imaginable, il ne remplit pas la implemented prérequis. Vous ne pouvez pas utiliser le code qui n'est pas implémenté. Je veux dire que vous devez indiquer comment le trouver puisqu'il n'est pas disponible par défaut et n'est pas bien connu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X