“学习Scala中的并发编程”中的一个例子:
package org.learningconcurrency
import java.io.File
import java.util.concurrent.atomic.AtomicReference
import java.util.concurrent.{ConcurrentHashMap, ForkJoinPool, LinkedBlockingQueue}
import org.apache.commons.io.FileUtils
import scala.annotation.tailrec
/**
* Created by kaiyin on 1/19/16.
*/
import org.learningconcurrency.ch3.Ch3.execute
import scala.collection.convert.decorateAsScala._
object Issue {
sealed trait State
class Idle extends State
class Creating extends State
class Copying(val n: Int) extends State
class Deleting extends State
class Entry(val isDir: Boolean) {
val state = new AtomicReference[State](new Idle)
}
class FileSystem(val root: String) {
val rootDir = new File(root)
val files: collection.concurrent.Map[String, Entry] = new ConcurrentHashMap[String, Entry]().asScala
for (f <- FileUtils.iterateFiles(rootDir, null, false).asScala)
files.put(f.getName, new Entry(false))
def deleteFile(filename: String): Unit = {
files.get(filename) match {
case None =>
log(s"Path '$filename' does not exist!")
case Some(entry) if entry.isDir =>
log(s"Path '$filename' is a directory!")
case Some(entry) => execute {
if (prepareForDelete(entry))
if (FileUtils.deleteQuietly(new File(filename)))
files.remove(filename)
}
}
}
}
@tailrec private def prepareForDelete(entry: Entry): Boolean = {
val s0 = entry.state.get
s0 match {
case i: Idle =>
if (entry.state.compareAndSet(s0, new Deleting)) true
else prepareForDelete(entry)
case c: Creating =>
log("File is being created, cannot delete")
false
case c: Copying =>
log("File is being created, cannot delete")
false
case d: Deleting =>
false
}
}
def main(args: Array[String]) {
val fs = new FileSystem("/tmp")
fs.files.foreach(println _)
// Thread.sleep(500)
fs.deleteFile("test")
}
}
它只是检查一个文件的状态然后删除它,代码看起来应该可以工作,但是在运行之后,我touch /tmp/test
创建的文件仍然存在。
答案 0 :(得分:0)
问题与FileUtils.deleteQuietly(new File(filename))
行有关。根据{{3}},deleteQuietly与File.delete()
相同,但不是引发异常,而是在文件被删除时返回true
,如果不是,则返回false
。
添加调试日志会显示deleteQuietly
无效:
if (FileUtils.deleteQuietly(new File(filename))) {
println("File was deleted!")
files.remove(filename)
} else {
println("File was NOT deleted!")
}
应打印File was NOT deleted
。
那有什么不对?让我们检查您传递给deleteQuietly
的参数:
println((new File(filename)).exists()) // returns false
似乎File
找不到您的文件。缺少什么?
由于您只提供相对路径test
,因此您还需要提供父目录:
case Some(entry) => execute {
if (prepareForDelete(entry))
if (FileUtils.deleteQuietly(new File(rootDir, filename)))
files.remove(filename)
}