2014-05-22 63 views
0

我有一个作为后台服务运行的Java(必须是Java 6兼容)应用程序。应用程序从文件系统读取文件(只读)。由于它是一项服务,我不想在阅读时锁定这些文件。尽管如此,如果有人在阅读时写入文件,我希望我的应用程序失败。使FileInputStream在并发写入时失败

这里是一个小测试,我设置了(其实用Scala编写):首先,我创建一个随机的内容有10 MB的文件:

$ dd if=/dev/urandom of=/tmp/random bs=1m count=10 

然后这里是我的测试:

package de.choffmeister.iotest 

import org.specs2.mutable._ 
import java.io._ 
import scala.language.reflectiveCalls 

class IOSpec extends Specification { 
    "Application" should { 
    "run" in { 
     using(new FileInputStream("/tmp/random")) { fs => 
     val buffer = new Array[Byte](1024) 
     var done = false 

     while (!done) { 
      println("Reading 1 kB") 
      val read = fs.read(buffer, 0, buffer.length) 
      if (read > 0) { 
      Thread.sleep(100) 
      } else done = true 
     } 

     ok 
     } 
    } 
    } 

    def using[A <: { def close(): Unit }, B](closable: A)(inner: A => B): B = { 
    try { 
     inner(closable) 
    } finally { 
     closable.close() 
    } 
    } 
} 

对于那些你不熟悉Scala的人来说:它只是一个简单的循环,以1 KB块的形式从头到尾读取文件。在每次阅读之间,都会有一次睡眠,这样整个过程需要几秒钟的时间。

现在,当我在阅读时(并因此在打开FileInputStream时)重写时,我的应用程序只是认为文件已被读取并且完成没有错误。

如何让我的应用程序在读取时操作文件的情况下抛出异常?再说一遍:我想在阅读时允许更改文件。我只想让我的应用程序注意,以便它可以例如重试。

+0

我会从这里开始:http://docs.oracle.com/javase/tutorial/essential/io/notification.html – jaco0646

+0

这是潜在的整个文件夹结构的文件通知。我需要少一点:我只想知道我目前正在阅读的文件是否已更改...而java.nio.FileWatcher仅适用于Java 7及更高版本。我需要一个Java 6解决方案(错过了,sry)。此外,使用独立的观察方法会引入许多竞争条件。当我完成阅读,并在1毫秒后获得通知时,该文件被修改:在更改之前或之后是否完成了阅读? – Thekwasti

+0

只要您确定修改后没有任何东西会将其重置为其原始值,您可以看到最后修改时间是否在打开和完成阅读之间发生了变化。 – wingedsubmariner

回答

0

1)如果文件仅追加,跟踪它以字节为单位的长度 - 如果改变读取之间,必须有别人

2)轮询time of last modification,如果有变化,必须有某人否则

+0

是的,我已经考虑过最后一次修改的时间......这些文件可能会随意更改,因此解决方案1)不适合。 – Thekwasti