File
syntax
listAllFilesRecursively
listAllFilesRecursively
in import extras.scala.io.file.syntax
listAllFilesRecursively
returns all files and directories in the givenFile
as well as the given file itself if it is a directory.- If it's a file, it returns a
List
containing the givenFile
.
The result of listAllFilesRecursively
is not sorted, so you need to sort it yourself.
e.g.)
listAllFilesRecursively("path/to/file").sorted
e.g.) If the file structure looks like this
/tmp/a
├── b
│ ├── b-1
│ │ ├── b-1-1.txt
│ │ ├── b-1-2.txt
│ │ └── b-1-3.txt
│ └── b-2
│ ├── b-2-1
│ │ ├── b-2-1-1.txt
│ │ └── b-2-1-2.txt
│ └── b-2-2
├── c
│ └── c-1.txt
└── d
├── d-1
│ ├── d-1-1.txt
│ ├── d-1-2.txt
│ ├── d-1-3.txt
│ ├── d-1-4.txt
│ └── d-1-5.txt
├── d-2.txt
└── d-3.txt
the result of listAllFilesRecursively
looks like this.
import extras.scala.io.file.syntax._
import java.io.File
listAllFilesRecursively(new File("/tmp/a")).sorted
// List(
// /tmp/a,
// /tmp/a/b,
// /tmp/a/b/b-1,
// /tmp/a/b/b-1/b-1-1.txt,
// /tmp/a/b/b-1/b-1-2.txt,
// /tmp/a/b/b-1/b-1-3.txt,
// /tmp/a/b/b-2,
// /tmp/a/b/b-2/b-2-1,
// /tmp/a/b/b-2/b-2-1/b-2-1-1.txt,
// /tmp/a/b/b-2/b-2-1/b-2-1-2.txt,
// /tmp/a/b/b-2/b-2-2,
// /tmp/a/c,
// /tmp/a/c/c-1.txt,
// /tmp/a/d,
// /tmp/a/d/d-1,
// /tmp/a/d/d-1/d-1-1.txt,
// /tmp/a/d/d-1/d-1-2.txt,
// /tmp/a/d/d-1/d-1-3.txt,
// /tmp/a/d/d-1/d-1-4.txt,
// /tmp/a/d/d-1/d-1-5.txt,
// /tmp/a/d/d-2.txt,
// /tmp/a/d/d-3.txt
// )
or
new File("/tmp/a").listAllFilesRecursively.sorted
deleteAllRecursively
deleteAllRecursively
in import extras.scala.io.file.syntax
removes the given file and all the files and directories in it if the given file is a directory.
e.g.) If the file structure looks like this
/tmp/a
├── b
│ ├── b-1
│ │ ├── b-1-1.txt
│ │ ├── b-1-2.txt
│ │ └── b-1-3.txt
│ └── b-2
│ ├── b-2-1
│ │ ├── b-2-1-1.txt
│ │ └── b-2-1-2.txt
│ └── b-2-2
├── c
│ └── c-1.txt
└── d
├── d-1
│ ├── d-1-1.txt
│ ├── d-1-2.txt
│ ├── d-1-3.txt
│ ├── d-1-4.txt
│ └── d-1-5.txt
├── d-2.txt
└── d-3.txt
deleteAllRecursively
deletes the given file and everything in it.
import extras.scala.io.file.syntax._
import java.io.File
deleteAllRecursively(new File("/tmp/a"))
// The `/tmp/a` and everything inside is removed.
or
new File("/tmp/a").deleteAllRecursively()
TempFiles
runWithTempDir
If you want to do something any temporary folder which should be deleted once it's done, you can use extras.scala.io.file.TempFiles.runWithTempDir
.
import extras.scala.io.file.TempFiles
import java.io.File
def foo(file: File): Unit =
if (file.exists)
println(s"${file.getParentFile.getName}/${file.getName} exists")
else
println(s"${file.getParentFile.getName}/${file.getName} does not exist.")
var tmp: Option[File] = None
// tmp: Option[File] = None
TempFiles.runWithTempDir("temporary-dir-prefix") { tempDir =>
tmp = Some(tempDir.value) // To check if the directory exists outside this block.
tmp.foreach(foo)
val tmpDir = tempDir.value
val someFile = new File(tmpDir, "myfile.txt")
someFile.createNewFile()
foo(someFile)
val someFile2 = new File(tmpDir, "myfile2.txt")
foo(someFile2)
"Done"
}
// tmp/temporary-dir-prefix3259597575880943802 exists
// temporary-dir-prefix3259597575880943802/myfile.txt exists
// temporary-dir-prefix3259597575880943802/myfile2.txt does not exist.
// res1: Either[Throwable, String] = Right(value = "Done")
tmp.foreach{ file =>
println(s"${file.getParentFile.getName}/${file.getName}")
foo(file)
}
// tmp/temporary-dir-prefix3259597575880943802
// tmp/temporary-dir-prefix3259597575880943802 does not exist.
/* the someFile (File(tmpDir, "myfile.txt") is deleted before TempFiles.runWithTempDir returns the result */
tempDir
is of type TempDir
which is just this value class.
final case class TempDir(value: java.io.File) extends AnyVal
TempFiles.runWithTempDir
is useful when you test with files and need to remove them once the test is done.
Example: test with hedgehog
import hedgehog._
import hedgehog.runner._
import extras.scala.io.file.TempFiles
import java.io._
import scala.util.Using
object MyTest extends Properties {
def tests: List[Test] = List(
property("test something with files", testSomethingWithFiles)
)
def testSomethingWithFiles: Property = for {
filename <- Gen.string(Gen.alphaNum, Range.linear(3, 5)).log("filename")
content1 <- Gen.string(Gen.alphaNum, Range.linear(10, 100)).log("content1")
content2 <- Gen.string(Gen.alphaNum, Range.linear(10, 100)).log("content2")
} yield {
val content = s"$content1\n$content2"
TempFiles.runWithTempDir("my-temp-dir") { tempDir =>
val rootDir = tempDir.value
val file = new File(rootDir, filename)
(for {
_ <- Using(new PrintWriter(file))(_.write(content))
result <- Using(scala.io.Source.fromFile(file))(_.mkString)
} yield result).toEither
}.joinRight match {
case Right(actual) => actual ==== content
case Left(err) => Result.failure.log(s"Failed: ${err.getMessage}")
}
}
}