2015-05-03 18 views
9

Cách xóa tệp độc đáo trong Scala, "cách Scala"?Scala - xóa tệp nếu tồn tại, cách Scala

Ví dụ, tôi có thể sử dụng một cái gì đó như thế này, rất Java phong cách:

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

Làm thế nào nó sẽ được triển khai tại Scala, trong một cú pháp chức năng hơn?

Trả lời

16

Bạn không thể loại bỏ các tác dụng phụ trong khi thực hiện các hoạt động IO, vì vậy không có các cách chức năng tốt ở đây. Tất cả các công cụ chức năng thực sự kết thúc khi bạn bắt đầu tương tác trực tiếp với người dùng/thiết bị, không có đơn nguyên nào có thể giúp bạn thực hiện một tác dụng phụ bên ngoài; tuy nhiên, bạn có thể mô tả (bọc) các tác dụng phụ liên tiếp bằng cách sử dụng IO giống như Monads.

Nói về ví dụ của bạn, mã đơn nguyên-restyled thể trông giống như:

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 

Nhưng đó là quá dài dòng mà không cần bất kỳ lợi thế thực sự nếu bạn chỉ muốn xóa một tập tin. Hơn thế nữa, kiểm tra fileTemp.exists không có ý nghĩa và thực sự không đáng tin cậy (như @Eduardo đã chỉ ra). Vì vậy, ngay cả trong Scala cách tốt nhất tôi biết là FileUtils.deleteQuietly:

FileUtils.deleteQuietly(new File(path)) 

Hoặc thậm chí

new File(path).delete() 

Nó sẽ không ném một ngoại lệ cho tập tin không tồn tại - chỉ trả false.

Nếu bạn thực sự muốn một cái gì đó hơn Scala chiều - nhìn vào rapture.io ví dụ:

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

Hoặc scala-io. Thông tin khác: How to do File creation and manipulation in functional style?

P.S. Tuy nhiên IO-monads có thể có ích (không giống như một số/Không trong trường hợp của tôi) khi bạn yêu cầu hoạt động không đồng bộ, mã rất ngây thơ (không có mèo/scalaz) sẽ như thế nào:

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 
} 

Tất nhiên, trong thế giới thực, tốt nhất nên sử dụng một số trình bao bọc NIO như FS2-io: https://lunatech.com/blog/WCl5OikAAIrvQCoc/functional-io-with-fs2-streams

+0

Chỉ cần nitpicking, nhưng, thay thế đầu tiên, có một khả năng nhỏ là tệp bị xóa bởi một quy trình khác giữa xác minh rằng nó tồn tại và tuyên bố xóa. – Eduardo

+0

@Eduardo và bạn đã có 'Không có gì ', điều đó là đúng :) – dk14

+0

@dk thì tại sao lại kiểm tra? – Eduardo

Các vấn đề liên quan