2014-05-22 2 views
0

J'ai une application Java (qui doit être compatible Java 6) exécutée en tant que service d'arrière-plan. L'application lit le fichier à partir du système de fichiers (lecture seule). Comme c'est un service, je ne veux pas verrouiller les fichiers en cours de lecture. Néanmoins, je veux que mon application échoue si quelqu'un d'autre écrit dans le fichier pendant que je lis.Échec de FileInputStream lors de l'écriture simultanée

Voici un petit test i mis en place (en fait écrit en scala): Tout d'abord créer un fichier de 10 Mo avec un contenu aléatoire:

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

Alors voici mon test:

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

Pour ceux d'entre vous qui ne connaissent pas Scala: C'est juste une simple boucle qui lit le fichier du début à la fin dans des blocs de 1 Ko. Entre chaque lecture, il y a un sommeil pour que tout le processus prenne quelques secondes.

Maintenant, quand je redéfinir le temps pendant la lecture (et donc pendant que mon FileInputStream est ouvert), alors mon application pense juste que le fichier a été lu au total et se termine sans erreur.

Comment puis-je faire en sorte que mon application lève une exception au cas où le fichier est manipulé pendant la lecture? Et encore: je veux permettre de changer le fichier en lisant. Je veux juste que ma demande le remarque afin qu'elle puisse par exemple réessayer.

+0

Je voudrais commencer ici: http://docs.oracle.com/javase/tutorial/essential/io/notification.html – jaco0646

+0

Ceci est une notification de fichier pour potentiellement une structure de dossier entier. J'ai besoin de beaucoup moins: je veux seulement savoir si mon fichier que je suis en train de lire est changé ... Et java.nio.FileWatcher est Java 7 et plus seulement. J'ai besoin d'une solution Java 6 (manquée, sry). En outre, l'utilisation d'une approche d'observation séparée introduit de nombreuses conditions de course. Quand j'ai fini de lire et d'obtenir 1 ms plus tard la notification, que le fichier a été modifié: Ai-je fini de lire avant ou après ce changement? – Thekwasti

+0

Vous pouvez voir si la dernière heure modifiée a changé entre l'ouverture et la fin de la lecture, tant que vous êtes sûr que rien ne la réinitialisera à sa valeur d'origine après une modification. – wingedsubmariner

Répondre

0

1) Si le fichier est seulement ajouté, suivre sa longueur en octets - si cela est changé entre les lectures, il doit y avoir quelqu'un d'autre

2) interroger le time of last modification, s'il y a un changement, il doit y avoir quelqu'un

+0

Ouais j'ai déjà pensé à l'heure de la dernière modification ... Les fichiers pourraient être altérés arbitrairement, donc la solution 1) ne convient pas. – Thekwasti

Questions connexes