Удалить каталог рекурсивно в Scala

21
задан Dan Ciborowski - MSFT 6 April 2019 в 16:09
поделиться

6 ответов

Попробуйте этот код, который выдает исключение в случае сбоя:

def deleteRecursively(file: File): Unit = {
  if (file.isDirectory) {
    file.listFiles.foreach(deleteRecursively)
  }
  if (file.exists && !file.delete) {
    throw new Exception(s"Unable to delete ${file.getAbsolutePath}")
  }
}

Вы также можете свернуть или отобразить удаление, если хотите вернуть значение для всех удалений.

23
ответ дан VasiliNovikov 6 April 2019 в 16:09
поделиться

С чистым scala + java way

import scala.reflect.io.Directory

val directory = new Directory(new File("/sampleDirectory"))
directory.deleteRecursively()

deleteRecursively () Возвращает false при ошибке

14
ответ дан Sukumaar 6 April 2019 в 16:09
поделиться

Использование API Java NIO.2:

import java.nio.file.{Files, Paths, Path, SimpleFileVisitor, FileVisitResult}
import java.nio.file.attribute.BasicFileAttributes

def remove(root: Path): Unit = {
  Files.walkFileTree(root, new SimpleFileVisitor[Path] {
    override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = {
      Files.delete(file)
      FileVisitResult.CONTINUE
    }
    override def postVisitDirectory(dir: Path, exc: IOException): FileVisitResult = {
      Files.delete(dir)
      FileVisitResult.CONTINUE
    }
  })
}

remove(Paths.get("/tmp/testdir"))

Действительно, очень жаль, что API NIO.2 работает с нами в течение стольких лет, и тем не менее его используют немногие, даже если действительно превосходит старый File API.

4
ответ дан Vladimir Matveev 6 April 2019 в 16:09
поделиться

Становится немного длиннее, но вот тот, который сочетает в себе рекурсивность решения Гарретта с npe-безопасностью исходного вопроса.

def deleteFile(path: String) = {
  val penultimateFile = new File(path.split('/').take(2).mkString("/"))
  def getFiles(f: File): Set[File] = {
    Option(f.listFiles)
      .map(a => a.toSet)
      .getOrElse(Set.empty)
  }
  def getRecursively(f: File): Set[File] = {
    val files = getFiles(f)
    val subDirectories = files.filter(path => path.isDirectory)
    subDirectories.flatMap(getRecursively) ++ files + penultimateFile
  }
  getRecursively(penultimateFile).foreach(file => {
    if (getFiles(file).isEmpty && file.getAbsoluteFile().exists) file.delete
  })
}
1
ответ дан Julian Peeters 6 April 2019 в 16:09
поделиться

Расширение решения Владимира Матвеева NIO2:

object Util {
  import java.io.IOException
  import java.nio.file.{Files, Paths, Path, SimpleFileVisitor, FileVisitResult}
  import java.nio.file.attribute.BasicFileAttributes

  def remove(root: Path, deleteRoot: Boolean = true): Unit =
    Files.walkFileTree(root, new SimpleFileVisitor[Path] {
      override def visitFile(file: Path, attributes: BasicFileAttributes): FileVisitResult = {
        Files.delete(file)
        FileVisitResult.CONTINUE
      }

      override def postVisitDirectory(dir: Path, exception: IOException): FileVisitResult = {
        if (deleteRoot) Files.delete(dir)
        FileVisitResult.CONTINUE
      }
    })

  def removeUnder(string: String): Unit = remove(Paths.get(string), deleteRoot=false)

  def removeAll(string: String): Unit = remove(Paths.get(string))

  def removeUnder(file: java.io.File): Unit = remove(file.toPath, deleteRoot=false)

  def removeAll(file: java.io.File): Unit = remove(file.toPath)
}
1
ответ дан Mike Slinn 6 April 2019 в 16:09
поделиться

Что я закончил с

def deleteRecursively(f: File): Boolean = {
  if (f.isDirectory) f.listFiles match {
    case files: Array[File] => files.foreach(deleteRecursively)
    case null =>
  }
  f.delete()
}
1
ответ дан 29 November 2019 в 00:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: