scalaスクリプト内からファイルa.txtをnewDir /にコピーしたい。Javaこれは、2つのファイルに対して2つのファイルストリームを作成することによって行われます。 、a.txtからバッファに読み込み、新しいファイルのFileOutputStreamに書き込みます。これをscalaで実現するためのより良い方法はありますか?scala.tools.nsc.io._にある可能性があります。検索しましたができませんでした。多くを見つける。
パフォーマンス上の理由から、コピーには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
であることを確認します。
特に Apache Commons IO および FileUtils.copyFile() を使用しないのはなぜですか? FileUtilsには、ファイル/ディレクトリなどをコピーするための多数のメソッドがあることに注意してください。
Java 7がリリースされ、別のオプションがあります:Java.nio.file.Files.copy
。おそらく最も簡単な解決策(そしてScalasの優れた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
を使い始める必要があります。
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)には調整が必要な場合があることに注意してください。
雇う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倍の%%を追加でき、機能します...
速度をあまり気にしない場合は、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は、ファイルを1行ずつ解析するという面倒な作業をすべて行っており、実際に行を処理せずに、ファイルを再度書き出すだけです。バイト読み取り/書き込みの使用Javaスタイルはかなり高速になります(前回ベンチマークしたときの約2〜3倍)。
編集:2.8は改行を食べるので、書き込みに戻す必要があります。
外部で何も使用したくない場合は、Javaで使用するのと同じように使用してください。いいことは、できるということです。
Scalax にはscalax.io.FileExtras.copyTo(dest:File)があります。しかし、開発は止まったようです。