Подтвердить что ты не робот

Scala script для копирования файлов

Я хочу скопировать файл a.txt в newDir/из scala script. В java это будет сделано путем создания 2 потоков файлов для 2-х файлов, чтения в буфер из a.txt и записи его в FileOutputStream нового файла. Есть ли лучший способ достичь этого в scala? Может быть что-то в scala.tools.nsc.io._. Я искал вокруг, но не мог найти много.

4b9b3361

Ответ 1

По соображениям производительности лучше использовать java.nio.Channel для копирования.

Список copy.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 )

Чтобы попробовать, создайте файл с именем test.txt со следующим содержимым:

Hello World

После создания test.txt запустите в командной строке следующее:

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

Убедитесь, что test-copy.txt имеет Hello World в качестве своего содержимого.

Ответ 2

Почему бы не использовать Apache Commons IO и FileUtils.copyFile( ) в частности? Обратите внимание, что FileUtils имеет большое количество методов для копирования файлов/каталогов и т.д.

Ответ 3

Java 7 теперь выключен, и у вас есть другой вариант: java.nio.file.Files.copy. Вероятно, самое простое решение (и с Scalas superior import еще проще). Если from и to являются строками, как в вашем вопросе:

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)

Конечно, вы должны начать использовать java.nio.file.Paths вместо строк.

Ответ 4

Если вы действительно хотите сделать это самостоятельно, вместо использования библиотеки, такой как commons-io, вы можете сделать следующее в версии 2.8. Создайте вспомогательный метод "use". Это даст вам форму автоматического управления ресурсами.

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

Затем вы можете определить способ копирования следующим образом:

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

Обратите внимание, что размер буфера (здесь: 1024) может нуждаться в некоторой настройке.

Ответ 5

Если вы не слишком заботитесь о скорости, вы можете немного облегчить свою жизнь, прочитав файл с помощью scala.io.Source(эта реализация для 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()
}

Но исходный код все время разбирается в файле по строкам, а затем вы просто записываете его, не обрабатывая строки. Использование байта для чтения/записи Java-стиля будет значительно быстрее (примерно 2-3 раза в последний раз, когда я проверил его).


Изменить: 2.8 ест символы новой строки, поэтому вам нужно добавить их обратно в запись.

Ответ 6

Аренда sbt.IO. Он чистый scala, он может копировать только измененные файлы, имеет полезные подпрограммы, такие как copyDirectory, delete, listFiles и т.д. Вы можете использовать его следующим образом:

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

Обратите внимание, что вы должны добавить правильную зависимость:

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

ИЗМЕНИТЬ: На самом деле это не очень хороший подход, поскольку зависимость "org.scala-sbt" % "io" % "version" была скомпилирована с использованием конкретной версии scala, и теперь вы не можете использовать ее с версией 2.10.X scala. Но, возможно, в будущем вы сможете добавить двойную %% в свою зависимость, например "org.scala-sbt" %% "io" % "version", и она будет работать...

Ответ 7

Если вы не хотите использовать что-либо внешнее, просто сделайте это так, как вы бы сделали это на Java. Самое приятное, что вы можете.

Ответ 8

Scalax имеет scalax.io.FileExtras.copyTo(dest: File). Но развитие, похоже, прекратилось.

Ответ 9

Из scala -io documentation:

import scalax.io._
import Resource._

fromFile("a.txt") copyDataTo fromFile("newDir/a.txt")