Scala скрипт для копирования файлов - PullRequest
25 голосов
/ 09 февраля 2010

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

Ответы [ 9 ]

36 голосов
/ 14 июля 2010

Из соображений производительности лучше использовать 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 в качестве содержимого.

32 голосов
/ 09 февраля 2010

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

20 голосов
/ 11 сентября 2012

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 вместо строк.

9 голосов
/ 12 июня 2010

Если вы действительно хотите сделать это самостоятельно, вместо использования библиотеки, такой как 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) может нуждаться в некоторой настройке.

3 голосов
/ 15 октября 2013

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

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

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

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

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

2 голосов
/ 09 февраля 2010

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

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


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

1 голос
/ 09 февраля 2010

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

0 голосов
/ 11 июля 2013

С документация scala-io :

import scalax.io._
import Resource._

fromFile("a.txt") copyDataTo fromFile("newDir/a.txt")
0 голосов
/ 09 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...