Quiero copiar el archivo a.txt a newDir/desde dentro de un guión de scala.
En java esto se llevaría a cabo mediante la creación de 2 secuencias de archivo para los 2 archivos, la lectura en búfer de a.txt y la escritura a la FileOutputStream del nuevo archivo.
Existe una mejor manera de lograr esto en scala? Puede ser algo en la scala.herramientas.nsc.io._. He buscado por ahí, pero no podía encontrar mucho.

InformationsquelleAutor kulkarni | 2010-02-08

9 Comentarios

  1. 36

    Por razones de rendimiento es mejor usar java.de nio.Canal para hacer la copia.

    Listado de copia.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 )

    Para probar esto, cree un archivo llamado test.txt con el siguiente contenido:

    Hello World

    Después de la creación de test.txt, ejecute lo siguiente desde la línea de comandos:

    scala copy.scala test.txt test-copy.txt

    Comprobar que test-copy.txt ha Hello World como su contenido.

    • De un lado-beneficio de mi solución es que es compatible con archivos binarios. Un efecto secundario es que te ata a Java, que es mala, si usted tiene la intención de ejecutar su Scala código .NET.
    • Que también es mucho más agradable código de tratar con los bytes a ti mismo.
    • Esta es una gran respuesta y debe ser aceptada solución de la OMI. Una cosa a tener en cuenta, puede que tenga que llamar dest.createNewFile como el FileInputStream fallará si dest no existe. También, usted puede necesitar dest.getCanonicalFile.getParentFile.mkdirs para crear cualquier padre directorios de la dest archivo.
    • Se puede cancelar la transferencia desde otro actor? (suponga que es un tiempo de transferencia y el usuario decide abortar)
    • sí, de hecho. FileChannel es un InterruptibleChannel que soporta la operación de cancelación a través de cerrar() en origen o de destino del canal y a través de Hilo#interrupción(). Usted podría llamar a Hilo#interrupción() en el actor del hilo de alguna manera, pero es más la intención de revelar a conservar una referencia a la fuente y de canal de llamada cerrar() en él para detener la transferencia.
  2. 33

    ¿Por qué no utilizar Apache Commons IO y FileUtils.copyFile() en particular ? Tenga en cuenta que FileUtils tiene un gran número de métodos para copiar los archivos/directorios, etc.

    • Votada abajo ¿por qué ? La reutilización de un componente existente para este parece pragmático para mí.
    • Se me ocurren un par de razones: no idiomáticas Scala, el enlace está roto, y se introduce un 181 KB de dependencia en su proyecto para algo que podría ser escrito en menos de 10 líneas de código (hay que admitir que uno es discutible). Pero el más destacado de la respuesta de abajo muestra cómo lograr esto con el built-in de java.de nio.
    • Enlace fijo. Como para la introducción de un 181Kb dependencia, yo no se preocupe. Además, es bastante probable que no estés utilizando, tales libs ya, y me volvería a investigar este tipo de bibliotecas para los servicios públicos como este, en lugar de poner su propio ‘utilidad’ de la biblioteca de hacer algo similar
    • La introducción de la 3ª parte de las dependencias está bien siempre y cuando usted está construyendo el producto final. Si va a enviar el código para que se ejecute dentro de otra aplicación, usted sería la introducción de dependencias transitivas que no es una buena idea, especialmente para algo tan simple como esto.
  3. 21

    Java 7 es ahora y tienes otra opción: java.nio.file.Files.copy. Probablemente la solución más sencilla (Y con Scala superior import aún más fácil). Siempre que from y to son cadenas como en tu pregunta:

    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)

    Por supuesto, usted debe comenzar a usar java.nio.file.Paths en lugar de cadenas.

  4. 9

    Si usted realmente desea hacerlo usted mismo en lugar de utilizar una biblioteca como la de commons-io, puede hacer lo siguiente en la versión 2.8. Crear un método helper «uso». Se le dará un formulario de la administración automática de recursos.

    def use[T <: { def close(): Unit }](closable: T)(block: T => Unit) {
      try {
        block(closable)
      }
      finally {
        closable.close()
      }
    }

    A continuación, puede definir un método de copia como esta:

    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 , _) }
        }
      }
    }

    Tenga en cuenta que el tamaño del búfer (aquí: 1024) podría necesitar algunos ajustes.

    • De la OMI, el nio.Canal solución es mucho más simple
    • este enfoque se puede utilizar a través de muchos más tipos de Flujos
    • El nio es, de hecho, más simple, pero este fragmento es tan cool! Clásico De La Scala.
  5. 3

    De coches sbt.IO. Es pura scala, puede copiar sólo los archivos que han cambiado, ha útiles rutinas como copyDirectory, delete, listFiles etc . Se puede utilizar como sigue:

    import sbt._
    IO.copyFile(file1, file2)

    Nota usted debe agregar adecuada de dependencia:

    libraryDependencies += "org.scala-sbt" % "io" % "0.13.0"

    EDITAR:
    En realidad este no es un buen enfoque, ya que la dependencia "org.scala-sbt" % "io" % "version" fue compilado utilizando particular scala versión y por ahora no se puede utilizar con 2.10.X scala versión. Pero quizás en el futuro se le puede agregar el doble de %% en que dependencia como "org.scala-sbt" %% "io" % "version" y funcionará…

  6. 2

    Si usted no se preocupan demasiado acerca de la velocidad, usted puede hacer su vida un poco más fácil de leer el archivo usando scala.io.Fuente (esta aplicación es para 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()
    }

    Pero la Fuente va a todos los problemas de analizar el archivo línea por línea, y luego sólo tienes que escribir de nuevo sin el procesamiento de las líneas. El uso de bytes de lectura/escritura de Java estilo será mucho más rápido (sobre 2-3x última vez que me comparan con ella).


    Edición: 2.8 come saltos de línea, así que usted tiene que agregarlos de nuevo en la escritura.

    • Yo podría tener un gran número de archivos y de los diferentes tipos de archivos a copiar. Los archivos también se puede bastante grandes en tamaño. Iba a sorber() o cualquier otra api en el scalax ayuda?
    • En ese caso, yo diría Brian sugerencia es la de la derecha–usa el Apache Commons IO. Está hecho para hacer lo que usted quiera, y de la Scala es el uso de bibliotecas de Java.
    • -1. Se mete saltos de línea en mi sistema.
    • Esta respuesta era para 2.7.7, como he dicho. 2.8 come saltos de línea. Usted también tendrá que agregar () después de getLines en 2.8.
    • Ah, no sabía que cambió la aplicación! Cambiado a +1
    • Lo siento, pero no puedo eliminar archivo de destino después de que su copia. Sin duda, debemos hacer que sea aceptado respuesta.

  7. 1

    Si no quiero usar nada externo, no como lo habría hecho en Java. Lo bueno, es que se puede.

Dejar respuesta

Please enter your comment!
Please enter your name here