用于复制文件的Scala脚本

时间:2010-02-08 22:02:32

标签: scala file copy

我想在scala脚本中将文件a.txt复制到newDir /。 在java中,这可以通过为2个文件创建2个文件流,从a.txt读取缓冲区并将其写入新文件的FileOutputStream来完成。 有没有更好的方法来实现这个scala?可能是scala.tools.nsc.io._中的内容。我四处寻找但找不到多少。

10 个答案:

答案 0 :(得分:36)

出于性能原因,最好使用 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作为其内容。

答案 1 :(得分:32)

为什么不特别使用Apache Commons IOFileUtils.copyFile()?请注意,FileUtils有许多方法可以复制文件/目录等。

答案 2 :(得分:20)

Java 7现已推出,您还有另一种选择:java.nio.file.Files.copy。最简单的解决方案(并且Scalas优越import更容易)。前提是fromto是您问题中的字符串:

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而不是字符串。

答案 3 :(得分:9)

如果您真的想自己动手而不是像commons-io这样的库,可以在2.8版本中执行以下操作。创建一个帮助方法“使用”。它将为您提供一种自动资源管理形式。

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)可能需要进行一些调整。

答案 4 :(得分:3)

雇用 sbt.IO 。它是纯scala,它只能复制更改的文件,有copyDirectorydeletelistFiles等有用的例程。您可以按照以下方式使用它:

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",它会起作用......

答案 5 :(得分:2)

如果你不太关心速度,你可以通过使用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吃掉换行符,所以你必须在写入时添加它们。

答案 6 :(得分:1)

如果你不想在外部使用任何东西,那就像在Java中那样做。好的,就是你可以。

答案 7 :(得分:1)

通过os-lib项目,可以轻松地在Scala中复制文件:

os.copy(
  os.pwd/"src"/"test"/"resources"/"a_file.csv",
  os.pwd/"newDir"/"a_file.csv"
)

该库在引擎盖下使用java.niojava.io,但对最终用户隐藏了所有混乱。到目前为止,这是执行文件系统操作的最简单的现代方法。有关更多信息,请参见here

答案 8 :(得分:0)

Scalax有scalax.io.FileExtras.copyTo(dest:File)。但是发展似乎已经停止了。

答案 9 :(得分:-1)

来自scala-io documentation

import scalax.io._
import Resource._

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