Created
February 6, 2018 23:14
-
-
Save mkeskells/9cca911f083a906eef72833496daa3f0 to your computer and use it in GitHub Desktop.
sbt delete
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.{File, IOException} | |
import java.nio.file.attribute.BasicFileAttributes | |
import java.nio.file._ | |
object test extends App { | |
def copyFiles = { | |
target.mkdirs() | |
val process = new ProcessBuilder().command("xcopy","s:\\source","S:\\target","/s/h/e/k/f/c/i/q").inheritIO().start() | |
process.waitFor() | |
//wait for the SSD to flush - makes the timing stable | |
Thread.sleep(1000) | |
} | |
val target = new File("S:/target") | |
//warmup | |
copyFiles | |
IO.delete(target) | |
copyFiles | |
IO.newDelete(target) | |
for (i <- 1 to 5) { | |
copyFiles | |
time(s"old delete $i", IO.delete(target)) | |
copyFiles | |
time(s"new delete $i", IO.newDelete(target)) | |
} | |
def time (msg:String, fn: => Unit): Unit = { | |
val start = System.nanoTime() | |
fn | |
val end = System.nanoTime() | |
println(s"$msg took ${(end-start)/1000/1000.0} ms") | |
} | |
} | |
object IO { | |
import ErrorHandling._ | |
/** Returns the children of directory `dir` in a non-null array. */ | |
def listFiles(dir: File): Array[File] = wrapNull(dir.listFiles()) | |
private def wrapNull(a: Array[File]) = if (a == null) new Array[File](0) else a | |
/** Deletes each file or directory (recursively) in `files`. */ | |
def delete(files: Iterable[File]): Unit = files.foreach(delete) | |
///OLD code | |
/** Deletes `file`, recursively if it is a directory. */ | |
def delete(file: File): Unit = { | |
translate("Error deleting file " + file + ": ") { | |
val deleted = file.delete() | |
if (!deleted && file.isDirectory) { | |
delete(listFiles(file)) | |
file.delete | |
() | |
} | |
} | |
} | |
def newDelete(file: File): Unit = { | |
object deleter extends SimpleFileVisitor[Path] { | |
override def visitFile(path: Path, attr: BasicFileAttributes): FileVisitResult = { | |
Files.delete(path) | |
FileVisitResult.CONTINUE | |
} | |
override def postVisitDirectory(dir: Path, e: IOException): FileVisitResult = { | |
if (e eq null) { | |
Files.delete(dir) | |
FileVisitResult.CONTINUE | |
} else throw e // directory iteration failed | |
} | |
} | |
Files.walkFileTree(file.toPath, deleter) | |
} | |
} | |
object ErrorHandling { | |
def translate[T](msg: => String)(f: => T) = | |
try { | |
f | |
} catch { | |
case e: IOException => throw new TranslatedIOException(msg + e.toString, e) | |
case e: Exception => throw new TranslatedException(msg + e.toString, e) | |
} | |
def wideConvert[T](f: => T): Either[Throwable, T] = | |
try { | |
Right(f) | |
} catch { | |
case ex@(_: Exception | _: StackOverflowError) => Left(ex) | |
case err@(_: ThreadDeath | _: VirtualMachineError) => throw err | |
case x: Throwable => Left(x) | |
} | |
def convert[T](f: => T): Either[Exception, T] = | |
try { | |
Right(f) | |
} catch { | |
case e: Exception => Left(e) | |
} | |
def reducedToString(e: Throwable): String = | |
if (e.getClass == classOf[RuntimeException]) { | |
val msg = e.getMessage | |
if (msg == null || msg.isEmpty) e.toString else msg | |
} else | |
e.toString | |
} | |
sealed class TranslatedException (msg: String, cause: Throwable) | |
extends RuntimeException(msg, cause) { | |
override def toString = msg | |
} | |
final class TranslatedIOException (msg: String, cause: IOException) | |
extends TranslatedException(msg, cause) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment