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

问题描述 投票:12回答:1

如何很好地删除Scala中的文件,“Scala方式”?

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

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

如何在Scala中实现更强大的语法?

scala delete-file
1个回答
27
投票

在做IO操作时你不能摆脱副作用,所以这里没有好的功能方法。当你开始直接与用户/设备交互时,所有功能实际上都会结束,没有monad可以帮助你做一个外部副作用;但是,您可以使用IO-like Monads描述(包装)顺序副作用。

谈到你的例子,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

如果你真的想要更多的Scala方式 - 例如看看rapture.io

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

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

附:但是,当你需要异步操作时,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包装器,如FS2-iohttps://lunatech.com/blog/WCl5OikAAIrvQCoc/functional-io-with-fs2-streams

© www.soinside.com 2019 - 2024. All rights reserved.