Scala-удалить файл, если он существует, способом Scala

Как красиво удалить файл в Scala, "путь Scala"?

например, я могу использовать что-то вроде этого, очень Java стиль:

  private def deleteFile(path: String) = {
    val fileTemp = new File(path)
    if (fileTemp.exists) {
       fileTemp.delete()
    }
  }

Как это будет реализовано в Scala, в более функциональном синтаксисе?

1 ответов


вы не можете избавиться от побочных эффектов, а делать IO-операции, поэтому здесь нет хороших функциональных способов. Все функциональные вещи фактически заканчиваются, когда вы начинаете взаимодействовать с пользователем/устройствами напрямую, никакая монада не может помочь вам сделать один внешний побочный эффект; однако вы можете описать (обернуть) последовательные побочные эффекты, используя IO-как монады.

говоря о вашем примере, monad-restyled код может выглядеть так:

implicit class FileMonads(f: File) {
  def check = if (f.exists) Some(f) else None //returns "Maybe" monad
  def remove = if (f.delete()) Some(f) else None //returns "Maybe" monad
}

for {
  foundFile <- new File(path).check
  deletedFile <- foundFile.remove
} yield deletedFile

res11: Option[java.io.File] = None

но это слишком многословно, без каких-либо реальные преимущества, если вы просто хотите удалить один файл. Более того, fileTemp.exists проверка не имеет смысла и на самом деле не является надежной (как отметил @Eduardo). Итак, даже в Scala лучший способ, который я знаю, это пакета fileutils.deleteQuietly:

  FileUtils.deleteQuietly(new File(path))

или даже

  new File(path).delete()

он не будет выдавать исключение для несуществующего файла-просто верните false.

если вы действительно хотите что-то более-Скала-способ - посмотреть восхищение.Ио для пример:

  val file = uri"file:///home/work/garbage"
  file.delete()

или scala-io. Дополнительная информация: как сделать создание файлов и манипуляции в функциональном стиле?

P.S. однако IO-монады могут быть полезны (в отличие от некоторых/None в моем случае), когда вам требуются асинхронные операции, поэтому наивный код (без cats / scalaz) будет выглядеть так:

implicit class FileMonads(f: File) {
  def check = Future{ f.exists } //returns "Future" monad
  def remove = Future{ f.remove } //returns "Future" monad
}

for {
  exists <- new File(path).check
  _ <- if (exists) foundFile.remove else Future.unit
}

конечно, в реальном мире лучше всего использовать некоторые NIO-обертки, такие как FS2-io: https://lunatech.com/blog/WCl5OikAAIrvQCoc/functional-io-with-fs2-streams