MiniDigger/Hangar

View on GitHub
models/src/main/scala/ore/util/FileUtils.scala

Summary

Maintainability
A
1 hr
Test Coverage
package ore.util

import java.io.IOException
import java.lang.Long.numberOfLeadingZeros
import java.nio.file.attribute.BasicFileAttributes
import java.nio.file.{FileVisitResult, Files, Path, SimpleFileVisitor}

import com.typesafe.scalalogging

object FileUtils {

  private val Logger    = scalalogging.Logger("FileUtils")
  private val MDCLogger = scalalogging.Logger.takingImplicit[OreMDC](Logger.underlying)

  /**
    * Formats the number of bytes into a human readable file size
    * (e.g. 100.0 KB).
    *
    * Based on http://stackoverflow.com/a/24805871
    *
    * @param size The size in bytes
    * @return The formatted string
    */
  def formatFileSize(size: Long): String = {
    if (size < 1024) s"$size B"
    else {
      val z = (63 - numberOfLeadingZeros(size)) / 10
      f"${size.toDouble / (1L << (z * 10))}%.1f ${" KMGTPE".charAt(z)}%sB"
    }
  }

  /**
    * Deletes the directory at the specified [[Path]] with all of its contents.
    *
    * @param dir The directory to delete
    */
  def deleteDirectory(dir: Path)(implicit mdc: OreMDC): Unit = {
    if (Files.exists(dir)) {
      Files.walkFileTree(dir, new DeleteFileVisitor)
      ()
    } else {
      MDCLogger.debug(s"Tried to remove directory that doesn't exist: $dir")
    }
  }

  /**
    * Deletes the contents of a directory without deleteing the directory itself.
    *
    * @param dir The directory to clean
    */
  def cleanDirectory(dir: Path)(implicit mdc: OreMDC): Unit = {
    if (Files.exists(dir)) {
      Files.walkFileTree(dir, new CleanFileVisitor(dir))
      ()
    } else {
      MDCLogger.debug(s"Tried to clean directory that doesn't exist: $dir")
    }
  }

  /**
    * Represents a [[java.nio.file.FileVisitor]] which will recursively delete a directory
    * with all its contents.
    */
  private class DeleteFileVisitor(implicit mdc: OreMDC) extends SimpleFileVisitor[Path] {

    override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = {
      if (Files.exists(file)) {
        Files.delete(file)
      } else {
        MDCLogger.debug(s"Tried to remove file that doesn't exist: $file")
      }
      FileVisitResult.CONTINUE
    }

    override def postVisitDirectory(dir: Path, exc: IOException): FileVisitResult = {
      if (Files.exists(dir)) {
        Files.delete(dir)
      } else {
        MDCLogger.debug(s"Tried to remove directory that doesn't exist: $dir")
      }
      FileVisitResult.CONTINUE
    }

  }

  /**
    * Similar to [[DeleteFileVisitor]], except that it will only clean the folder
    * contents. It will not delete the given [[dir]].
    *
    * @param dir The directory to clean
    */
  private class CleanFileVisitor(private val dir: Path)(implicit mdc: OreMDC) extends DeleteFileVisitor {

    override def postVisitDirectory(dir: Path, exc: IOException): FileVisitResult = {
      if (dir != this.dir) {
        super.postVisitDirectory(dir, exc)
      } else {
        FileVisitResult.CONTINUE
      }
    }

  }

}