Scala - 如果存在则删除文件,Scala 方式

Scala - delete file if exist, the Scala way

如何在Scala中漂亮地删除文件,"the Scala way"?

例如,我可以使用这样的东西,非常Java风格:

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

如何在 Scala 中以更实用的语法实现它?

您无法在进行 IO 操作时消除副作用,因此这里没有好的功能方法。当您开始直接与 user/devices 交互时,所有功能性的东西实际上都结束了,没有 monad 可以帮助您做一个外部副作用;但是,您可以使用类似 IO 的 Monad 来描述(包装)顺序副作用。

关于您的示例,monad 重新设计的代码可能如下所示:

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()

它不会为不存在的文件抛出异常 - 只是 return false.

如果您真的想要更多 Scala 方式的东西 - 请查看 rapture.io 例如:

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

scala-io。 更多信息:How to do File creation and manipulation in functional style?

P.S。然而,当您需要异步操作时,IO-monads 可能很有用(不像 Some/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-wrappers,例如 FS2-io: https://lunatech.com/blog/WCl5OikAAIrvQCoc/functional-io-with-fs2-streams

os-lib 允许您优雅地删除存在的文件:

val file = os.pwd/"cats"/"cat1.txt"
if (os.exists(file)) os.remove(file)

os-lib 比直接使用 Java 库更简洁。有关库的更多详细信息,请参阅 here