J'ai une application qui écrit des informations dans un fichier. Ces informations sont utilisées après l'exécution pour déterminer la réussite / l'échec / l'exactitude de l'application. J'aimerais pouvoir lire le fichier au fur et à mesure de son écriture afin de pouvoir faire ces vérifications de réussite / échec / exactitude en temps réel.
Je suppose qu'il est possible de le faire, mais quels sont les pièges lors de l'utilisation de Java? Si la lecture rattrape l'écriture, attendra-t-elle simplement plus d'écritures jusqu'à ce que le fichier soit fermé, ou la lecture lèvera-t-elle une exception à ce stade? Si ce dernier, que dois-je faire alors?
Mon intuition me pousse actuellement vers BufferedStreams. Est-ce la voie à suivre?
Réponses:
Impossible de faire fonctionner l'exemple
FileChannel.read(ByteBuffer)
car il ne s'agit pas d'une lecture bloquante. J'ai cependant fait fonctionner le code ci-dessous:Bien sûr, la même chose fonctionnerait comme une minuterie au lieu d'un thread, mais je laisse cela au programmeur. Je cherche toujours un meilleur moyen, mais cela fonctionne pour moi pour le moment.
Oh, et je vais mettre cela en garde avec: j'utilise la version 1.4.2. Oui, je sais que je suis encore à l'âge de pierre.
la source
Si vous souhaitez lire un fichier pendant qu'il est en cours d'écriture et ne lire que le nouveau contenu, ce qui suit vous aidera à réaliser la même chose.
Pour exécuter ce programme, vous le lancerez à partir de l'invite de commande / de la fenêtre du terminal et passerez le nom du fichier à lire. Il lira le fichier à moins que vous ne supprimiez le programme.
java FileReader c: \ myfile.txt
Lorsque vous tapez une ligne de texte, enregistrez-la à partir du bloc-notes et vous verrez le texte imprimé dans la console.
la source
BufferedReader
création dans chaque appel de boucle est tellement inutile. Avec sa création une fois, le saut ne serait pas nécessaire, car le lecteur tamponné lirait les nouvelles lignes à mesure qu'elles arrivent.Vous pouvez également jeter un œil au canal java pour verrouiller une partie d'un fichier.
http://java.sun.com/javase/6/docs/api/java/nio/channels/FileChannel.html
Cette fonction du
FileChannel
pourrait être un débutUn appel de cette méthode bloquera jusqu'à ce que la région puisse être verrouillée
la source
Je suis totalement d'accord avec la réponse de Joshua , Tailer est apte à faire le travail dans cette situation. Voici un exemple :
Il écrit une ligne toutes les 150 ms dans un fichier, tout en lisant ce même fichier toutes les 2500 ms
la source
La réponse semble être "non" ... et "oui". Il ne semble y avoir aucun moyen réel de savoir si un fichier est ouvert à l'écriture par une autre application. Ainsi, la lecture d'un tel fichier progressera jusqu'à ce que le contenu soit épuisé. J'ai suivi les conseils de Mike et j'ai écrit du code de test:
Writer.java écrit une chaîne dans le fichier, puis attend que l'utilisateur appuie sur Entrée avant d'écrire une autre ligne dans le fichier. L'idée étant qu'il puisse être démarré, alors un lecteur peut être démarré pour voir comment il gère le fichier "partiel". Le lecteur que j'ai écrit est dans Reader.java.
Writer.java
Reader.java
Aucune garantie que ce code est la meilleure pratique.
Cela laisse l'option suggérée par Mike de vérifier périodiquement s'il y a de nouvelles données à lire à partir du fichier. Cela nécessite alors une intervention de l'utilisateur pour fermer le lecteur de fichiers lorsqu'il est déterminé que la lecture est terminée. Ou bien, le lecteur doit être informé du contenu du fichier et être en mesure de déterminer la condition de fin d'écriture. Si le contenu était XML, la fin du document pourrait être utilisée pour le signaler.
la source
Pas Java en soi, mais vous pouvez rencontrer des problèmes où vous avez écrit quelque chose dans un fichier, mais il n'a pas encore été écrit - il peut être dans un cache quelque part, et la lecture à partir du même fichier peut ne pas vous donner réellement les nouvelles informations.
Version courte - utilisez flush () ou tout autre appel système pertinent pour vous assurer que vos données sont réellement écrites dans le fichier.
Remarque Je ne parle pas du cache disque au niveau du système d'exploitation - si vos données entrent ici, elles devraient apparaître dans un read () après ce point. Il se peut que le langage lui-même mette en cache les écritures, en attendant qu'un tampon se remplisse ou que le fichier soit vidé / fermé.
la source
Il existe une queue graphique Java Open Source qui fait cela.
https://stackoverflow.com/a/559146/1255493
la source
Vous ne pouvez pas lire un fichier ouvert à partir d'un autre processus à l'aide de FileInputStream, FileReader ou RandomAccessFile.
Mais utiliser FileChannel directement fonctionnera:
la source
Je ne l'ai jamais essayé, mais vous devriez écrire un cas de test pour voir si la lecture d'un flux après avoir atteint la fin fonctionnera, indépendamment du fait qu'il y ait plus de données écrites dans le fichier.
Y a-t-il une raison pour laquelle vous ne pouvez pas utiliser un flux d'entrée / sortie canalisé? Les données sont-elles écrites et lues à partir de la même application (si oui, vous avez les données, pourquoi avez-vous besoin de lire à partir du fichier)?
Sinon, lisez peut-être jusqu'à la fin du fichier, puis surveillez les changements et cherchez là où vous vous êtes arrêté et continuez ... mais faites attention aux conditions de course.
la source