9
votes

Fichier non bloquant IO en Java

Je veux écrire sur un tuyau nommé (déjà créé) sans bloquer le lecteur. Mon lecteur est une autre application qui peut descendre. Si le lecteur tombe en panne, je souhaite que l'application écrivaine continue à écrire sur ce tuyau nommé. Quelque chose comme une ceci en Java xxx

de sorte que lorsque le lecteur arrive, il peut reprendre de l'endroit où il a échoué.


4 commentaires

Je ne sais pas si vous pouvez le faire avec un tuyau. Je crois que le tuyau est grillé si le lecteur ou l'écrivain est fermé. Il s'agit d'une citation du Javadoc pour PipedOutPutStream: "Le tuyau doit être cassé si un fil qui lisait la lecture d'octets de données à partir du flux d'entrée de canette connecté n'est plus vivant". Je ne pense pas qu'un tuyau cassé peut être corrigé.


@Jim Tough il parle d'un tuyau nommé ( Linuxjournal.com/article/2156 ). Pas le PipedOutPutStream de Java SDK.


Pas une réponse que vous pouvez accepter?


Signifiez-vous vraiment un tuyau nommé UNIX? Comme dans Créé avec MKFIFO?


4 Réponses :


2
votes

Si vous souhaitez que des tuyaux puissent rester actifs et faire la queue des messages, vous voulez probablement un système de messagerie plutôt qu'un tuyau brut. En Java, l'API standard s'appelle "Système de messagerie Java" ( JMS ), et il y a De nombreuses implémentations standard ... les plus courantes dont j'ai été vue d'être Apache Activemq . Si vous souhaitez une interface de plate-forme inter-plate-forme, une interface de sockets qui met la mémoire tampon et la récupération, je pourrais suggérer 0mq , qui Bien que ne pas être "pure java" a des liaisons pour de nombreuses langues et une excellente performance.


0 commentaires

8
votes

D'abord, j'essaie de répondre à vos questions. Ensuite, je vais essayer de vous montrer un extrait de code que j'ai créé qui résout votre problème en utilisant Blocking Io.

Vos questions

Je veux écrire à un tuyau nommé (déjà créé) sans bloquer sur le lecteur

Vous n'avez pas besoin de non bloquant IO pour résoudre votre problème. Je pense que cela ne peut même pas vous aider à résoudre votre problème. Le blocage IO sera également bon (peut-être encore mieux que non bloquant IO en raison de la faible concurrence). Un plus bloque IO est plus facile à programmer. Votre lecteur peut / devrait rester blocage.

Mon lecteur est une autre application qui peut descendre. Si le lecteur va bas, je veux que l'application écrivaine Neep écrit à la pipe nommée. De sorte que lorsque le lecteur arrive, il peut reprendre de l'endroit où il a échoué.

Il suffit de mettre les messages à l'intérieur d'une file d'attente de blocage. Ensuite, écrivez sur le tuyau nommé seulement lorsque le lecteur le lit (se produit automatiquement à cause du blocage de l'IO). Pas besoin de fichier non bloquant IO lorsque vous utilisez une file d'attente de blocage. Les données sont asynchrones livrées à partir de la file d'attente de blocage lors de la lecture d'un lecteur, qui a envoyé vos données de votre écrivain au lecteur.

quelque chose comme un fopen (FPATH, O_nonblock) en Java

Vous n'avez pas besoin de non-bloquage IO sur le lecteur et même si vous l'utilisiez. Utilisez simplement Blocking Io.

Code Snippet

A Créé un petit extrait que je crois démontre quels sont vos besoins.

composants:

  • écrivain.java : lit les lignes de la console à titre d'exemple. Lorsque vous démarrez le programme, entrez le texte suivi de Entrée qui l'a envoyé à votre tuyau nommé. L'écrivain reprendra écrire si nécessaire.
  • lecteur.java : lit les lignes écrites de votre tuyau nommé (écrivain.java).
  • tuyau nommé : Je suppose que vous avez créé un tuyau nommé "tuyau" dans le même répertoire.

    écrivain.java xxx

    lecteur.java xxx


0 commentaires

1
votes

S'il y avait une telle chose que l'E / S sans blocage d'E / S en Java, qu'il n'y a pas, une écriture à un tuyau nommé qui n'était pas lue reviendrait à zéro et ne pas écrire quoi que ce soit. Donc, non-blocage ne fait pas partie de la solution.

Il y a aussi le problème que les tuyaux nommés ont une taille tampon finie. Ils ne sont pas des files d'attente infinies, qu'il y ait un processus de lecture ou non. Je suis d'accord avec la suggestion de regarder JMS.


4 commentaires

Il y a un fichier non bloquant IO. Recherche de Nio ( en.wikipedia.org/wiki/new_i/o )


La référence définitive pour Nio et Java en général n'est pas Wikipedia mais le Javadoc, qui ne dit pas cela. La wikipedia non plus non plus pour cette affaire. Et Nio signifie «nouvel E / S», Wikipedia nonobstant.


Je sais que c'est un vieux Q / A, mais pour des raisons d'exactitude, il convient de souligner que Java 7 a asynchronousfilechannel .


@nilskp pour l'amour de l'exactitude, il convient de souligner que les E / S asynchrones ne sont pas la même chose que l'E / S non bloquant, et qu'une écriture asynchrone à un tuyau qui ne se limite jamais ne se terminerait jamais, ce qui ne fait pas partie de la solution non plus.



-1
votes

Vous devriez pouvoir utiliser Nio's asynch écrire code> sur une FIFO UNIX, comme vous le pouvez à tout autre fichier: xxx pré>

... ou .. . P>

 channel.write(..., myCompletionHandler);


2 commentaires

Si vous vérifiez Javadoc pour Asynchronousfilechannel, il est indiqué: "Un asynchronesfilechannel est associé à une piscine de fil ...". Donc, cette classe ne propose pas vraiment une API anti-blocking, juste ASYNC ...


Le principal problème avec l'utilisation de asynchronousfilechannel sur UNIX FIFOS est que l'opération écrire () (ainsi que lecture () ) nécessite une position d'écriture et Utilise ensuite recherche () sur le descripteur de fichier avant de l'écriture - qui est un grand non-non pour les FIFOs.