
com.mle.util.FileUtilities.scala Maven / Gradle / Ivy
The newest version!
package com.mle.util
import java.nio.file._
import com.mle.util.FileVisitors.FileCollectingVisitor
import Implicits._
import org.apache.commons.io.IOUtils
import java.io.{FileWriter, BufferedWriter, PrintWriter}
import Util._
/**
*
* @author mle
*/
object FileUtilities {
val lineSep = sys.props("line.separator")
val userDir = sys.props("user.dir")
var basePath = Paths get sys.props.getOrElse("app.home", userDir)
def init(appName: String) {
basePath = Paths get sys.props.get(appName + ".home").getOrElse(userDir)
}
def pathTo(location: String) = basePath / location
def listFiles(srcDir: Path, visitor: FileCollectingVisitor): Seq[Path] = {
// log debug "Reading " + srcDir.toAbsolutePath.toString
Files.walkFileTree(srcDir, visitor)
visitor.files
}
/**
* @see http://stackoverflow.com/a/4608061
* @param filename the file to write to
* @param op the file writing code
*/
def writerTo(filename: String)(op: PrintWriter => Unit): Path = {
val path = FileUtilities.pathTo(filename)
writerTo(path)(op)
path
}
/**
* @see http://stackoverflow.com/a/4608061
* @param filename the file to write to
* @param op the file writing code
*/
def writerTo(filename: Path)(op: PrintWriter => Unit) {
using(new PrintWriter(new BufferedWriter(new FileWriter(filename.toFile))))(op)
}
def readerFrom[T](path: Path)(code: Iterator[String] => T): T =
Util.resource(io.Source.fromFile(path.toFile)) {
source => code(source.getLines())
}
/**
* Avoids io.Source.fromURI(uri) because it seems to fail unless the supplied URI points to a file.
*
* @param resource
* @param code
* @tparam T
* @return
*/
def readerFrom[T](resource: String)(code: Iterator[String] => T): T = {
val maybeFile = FileUtilities pathTo resource
if (Files exists maybeFile) {
readerFrom(maybeFile)(code)
} else {
Util.using(Util.openStream(resource))(inStream => {
Util.resource(io.Source.fromInputStream(inStream))(source => code(source.getLines()))
})
}
}
/**
* Calculates the amount of used disk space, in percentages, according to the formula: usable_space / total_space. For example, if a 10 GB disk contains 3 GB of data, this method returns 30 for that disk.
* @param path the path to the disk or file store
* @return the amount of used disk space as a percentage [0,100] of the total disk space capacity, rounded up to the next integer
*/
def diskUsagePercentage(path: Path) = {
val fileStore = Files getFileStore path
val totalSpace = fileStore.getTotalSpace
val freeSpace = fileStore.getUsableSpace
math.ceil(100.0 * freeSpace / totalSpace).toInt
}
/**
* Copies the given files to a destination directory, where the files' subdirectory is calculated relative to the given base directory.
*
* @param srcBase the base directory for the source files
* @param files the source files to copy
* @param dest the destination directory, so each source file is copied to dest / srcBase.relativize(file)
* @return the destination files
*/
def copy(srcBase: Path, files: Set[Path], dest: Path) = files map (file => {
val destFile = rebase(file, srcBase, dest)
// Create parent dirs if they don't exist
val parentDir = destFile.getParent
if (parentDir != null && !Files.isDirectory(parentDir))
Files createDirectories parentDir
// Target directory guaranteed to exist, so copy the target, unless it is a directory that already exists
if (!Files.isDirectory(destFile))
Files.copy(file, destFile, StandardCopyOption.REPLACE_EXISTING)
else destFile
})
def rebase(file: Path, srcBase: Path, destBase: Path) = destBase resolve (srcBase relativize file)
/**
* Performs a recursive search of files and directories under the given base path.
* @param basePath the base directory
* @return The files and directories under the base directory. Directories precede any files they contain in the returned sequence.
*/
def listPaths(basePath: Path): Seq[Path] = {
val visitor = new FileVisitors.FileAndDirCollector
Files walkFileTree(basePath, visitor)
visitor.files
}
/**
* Creates the file referenced by the specified path and any non-existing parent directories. No-ops if the file already exists.
* @param path the path to the file to create
* @see [[java.nio.file.Files.createFile( )]], [[java.nio.file.Paths]]
*/
def createFile(path: String) {
val file = pathTo(path)
if (!Files.exists(file)) {
val maybeParent = file.getParent
if (maybeParent != null)
Files createDirectories file.getParent
Files createFile file
}
}
def propsToFile(props: String*) = {
props flatMap (prop => resourceToFile(sys.props(prop)))
}
/**
*
* @param resource the resource to lookup and write to file
* @return the path wrapped in an option if it was written, None if no file was written because it already existed
*/
def resourceToFile(resource: String): Option[Path] = {
val destFile = pathTo(resource)
if (!Files.exists(destFile)) {
val url = Util resource resource
val bytes = IOUtils.toByteArray(url)
Files.createDirectories(destFile.getParent)
Some(Files.write(destFile, bytes))
} else {
None
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy