Script Scala pour copier des fichiers
je veux copier le fichier a.txt pour newDir/ à partir de l'intérieur d'un script scala. En java, cela serait fait en créant 2 flux de fichiers pour les 2 fichiers, en lisant dans le tampon de a.txt et l'écrire dans le flux FileOutputStream du nouveau fichier. Y a-t-il un meilleur moyen d'y parvenir à scala? Peut-être quelque chose à scala.outils.nsc.io._. J'ai cherché partout mais impossible de trouver beaucoup.
9 réponses
Pour des raisons de performances, il est préférable d'utiliser java.nio.Canal pour effectuer la copie.
Inscription copier.scala:
import java.io.{File,FileInputStream,FileOutputStream}
val src = new File(args(0))
val dest = new File(args(1))
new FileOutputStream(dest) getChannel() transferFrom(
new FileInputStream(src) getChannel, 0, Long.MaxValue )
Pour essayer de créer un fichier appelé de test.txt avec le contenu suivant:
Hello World
après avoir créé de test.txt, exécutez ce qui suit depuis la ligne de commande:
scala copy.scala test.txt test-copy.txt
Vérifiez que test de copie.txt a Hello World
comme son contenu.
Pourquoi ne pas utiliser Apache Commons IO et FileUtils.copyFile () en particulier ? Notez que FileUtils a un grand nombre de méthodes pour copier des fichiers/répertoires etc.
Java 7 est maintenant disponible et vous avez une autre option:java.nio.file.Files.copy
. La solution probablement la plus facile (et avec Scalas superior import
encore plus facile). À condition que from
et to
sont des chaînes de caractères comme dans votre question:
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
import java.nio.file.Files.copy
import java.nio.file.Paths.get
implicit def toPath (filename: String) = get(filename)
copy (from, to, REPLACE_EXISTING)
bien sûr, vous devriez commencer à utiliser java.nio.file.Paths
au lieu de chaînes de caractères.
Si vous voulez vraiment le faire vous-même au lieu d'utiliser une bibliothèque comme commons-io, vous pouvez effectuer les opérations suivantes dans la version 2.8. Créer une méthode d'aide à "l'utilisation". Il vous donnera une forme de gestion automatique des ressources.
def use[T <: { def close(): Unit }](closable: T)(block: T => Unit) {
try {
block(closable)
}
finally {
closable.close()
}
}
Ensuite, vous pouvez définir une méthode de copie comme ceci:
import java.io._
@throws(classOf[IOException])
def copy(from: String, to: String) {
use(new FileInputStream(from)) { in =>
use(new FileOutputStream(to)) { out =>
val buffer = new Array[Byte](1024)
Iterator.continually(in.read(buffer))
.takeWhile(_ != -1)
.foreach { out.write(buffer, 0 , _) }
}
}
}
notez que la taille du buffer (ici: 1024) peut nécessiter quelques réglages.
si vous ne vous souciez pas trop de la vitesse, vous pouvez rendre votre vie légèrement plus facile en lisant le fichier en utilisant scala.io.Source (cette implémentation est pour 2.7.7):
def copyF(from: java.io.File, to: String) {
val out = new java.io.BufferedWriter( new java.io.FileWriter(to) );
io.Source.fromFile(from).getLines.foreach(s => out.write(s,0,s.length));
out.close()
}
mais Source va à tous les problèmes de l'analyse du fichier ligne par ligne, et puis vous venez de l'écrire à nouveau sans réellement traiter les lignes. L'utilisation de byte read / write Java style sera considérablement plus rapide (environ 2-3x la dernière fois que je l'ai référencé).
Edit: 2.8 mange des retours à la ligne, donc, vous devez les ajouter dans l'écriture.
embauche sbt.IO. C'est du pur scala, il ne peut copier que des fichiers modifiés, il a des routines utiles comme copyDirectory
,delete
, listFiles
etc. Vous pouvez l'utiliser comme suit:
import sbt._
IO.copyFile(file1, file2)
Remarque: vous devez ajouter adéquat de la dépendance:
libraryDependencies += "org.scala-sbt" % "io" % "0.13.0"
EDIT:
En fait, ce n'est pas une bonne approche, puisque la dépendance "org.scala-sbt" % "io" % "version"
a été compilé en utilisant la version scala particulière et pour l'instant vous ne pouvez pas l'utiliser avec 2.10.Version X scala. Mais peut-être que dans le futur vous will peut ajouter le double % % % dans votre dépendance comme "org.scala-sbt" %% "io" % "version"
et ça va marcher...
si vous ne voulez pas utiliser quelque chose d'externe, faites-le comme vous l'auriez fait en Java. La bonne chose est que vous pouvez.
import scalax.io._
import Resource._
fromFile("a.txt") copyDataTo fromFile("newDir/a.txt")