Simultanément en lecture/écriture de canal nommé en Java (sur windows)
Je suis en train d'assurer la communication entre une application en C# et Java application sur windows à l'aide de canaux nommés avec la méthode décrite par v01ver dans cette question: Comment ouvrir un pipe nommé Windows à partir de Java?
Je suis confronté à un problème sur le Java côté parce que j'ai un thread de lecture constamment en attente pour l'entrée sur le tuyau et quand j'essaye d'écrire pour le tuyau de mon thread principal, il se coince toujours.
final RandomAccessFile pipe;
try {
pipe = new RandomAccessFile("\\\\.\\pipe\\mypipe", "rw");
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
return;
}
Thread readerThread = new Thread(new Runnable() {
@Override
public void run() {
String line = null;
try {
while (null != (line = pipe.readLine())) {
System.out.println(line);
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}
});
readerThread.start();
try { Thread.sleep(500); } catch (InterruptedException e) {}
try {
System.out.println("Writing a message...");
pipe.write("Hello there.\n".getBytes());
System.out.println("Finished.");
}
catch (IOException ex) {
ex.printStackTrace();
}
La sortie est:
la Rédaction d'un message...
et puis il attend toujours.
Comment puis-je écrire à un canal nommé lors de l'attente pour l'entrée dans un autre thread?
...et vous ne pouvez pas éteindre et de ne pas éteindre la lecture? lecture seule si le fichier n'est pas à la fin, sinon bloquer sur
Il pourrait être utile d'utiliser JVisualVM pour voir si vous thread(s) sont bloqués à l'O/S ou la Java de la synchronisation de l'acquisition.
Plutôt que d'utiliser un tube nommé, vous pouvez le trouver à l'aide de sockets est plus évolutif (canaux sont mis en œuvre à l'aide de sockets sous Windows en tout cas), Vous trouverez plus d'exemples de comment les utiliser (comme ils le faisaient le plus souvent) qui devrait vous aider.
Lawrey: les canaux Nommés dans les Fenêtres ne sont PAS mises en œuvre à l'aide de sockets. Lorsque le client et le serveur sont sur la même machine, ils utilisent la mémoire partagée pour l'IPC et sont extrêmement rapides.
Les pipes de Java (nio) sont mis en œuvre via des sockets sur Windows et OS des tuyaux sur Linux. Native de Windows canaux nommés ne sont pas prises et leur impl. ne dépend pas de winsock. C'est juste de java qui ne les utilise pas car il n'est pas possible d'enregistrer le même sélecteur pour les sockets et windows tuyaux.
poll
un blocage de la file d'attente à attendre pour les écritures; et, finalement, l'utilisation d'un thread unique. si vous êtes intéressé je peux vous en montrer un extrait; cependant je n'ai pas de xp w/ named pipes comme ça et une simple prise est 10 fois plus facile à gérerIl pourrait être utile d'utiliser JVisualVM pour voir si vous thread(s) sont bloqués à l'O/S ou la Java de la synchronisation de l'acquisition.
Plutôt que d'utiliser un tube nommé, vous pouvez le trouver à l'aide de sockets est plus évolutif (canaux sont mis en œuvre à l'aide de sockets sous Windows en tout cas), Vous trouverez plus d'exemples de comment les utiliser (comme ils le faisaient le plus souvent) qui devrait vous aider.
Lawrey: les canaux Nommés dans les Fenêtres ne sont PAS mises en œuvre à l'aide de sockets. Lorsque le client et le serveur sont sur la même machine, ils utilisent la mémoire partagée pour l'IPC et sont extrêmement rapides.
Les pipes de Java (nio) sont mis en œuvre via des sockets sur Windows et OS des tuyaux sur Linux. Native de Windows canaux nommés ne sont pas prises et leur impl. ne dépend pas de winsock. C'est juste de java qui ne les utilise pas car il n'est pas possible d'enregistrer le même sélecteur pour les sockets et windows tuyaux.
OriginalL'auteur takteek | 2011-02-11
Vous devez vous connecter pour publier un commentaire.
Ce comportement est normal de tuyaux. Il est censé accrocher jusqu'à d'autres processus se connecte à la pipe et au lit.
OriginalL'auteur Eagle
Je suppose que
RandomAccessFile
est pas le droit a l'API ici. Essayez un FileInputStream + FileOutputStream sur le Java côté. Mais ce n'est qu'une supposition, que je la dernière utilisation de l'API Windows dans un temps où les canaux nommés n'existait pas encore.ŭlo, vous ne pouvez pas ouvrir le fichier w/ 2 descripteurs en lecture et en écriture. RadndomAccessFile est la voie à suivre si vous avez besoin de lire et d'écrire en même temps.
C'est le droit de l'API, elle correspond à CreateFile() de l'API WIN32.
OriginalL'auteur Paŭlo Ebermann
J'ai le même problème -- la communication entre un C#/Python application et une application Java sur windows à l'aide de canaux nommés:
Nous avons l'exemple de Code Client écrit en Java, mais en ligne
String echoResponse = pipe.readLine();
de la bande de roulement attend toujours.Solution du problème:
J'ai un ServerPipe code écrit sur le langage Python à partir d'ici Exemple Le Nom De Code De Tuyaux:
et d'exécuter ses sur Python 2.6.6
Serveur après avoir démarrer, vous pouvez utiliser la version légèrement modifiée de la Client Java code:
Il fonctionne bien dans NetBeans 6.9.1.
Ce n'est pas une réponse. Il doit avoir été validé comme une question distincte.
OriginalL'auteur Andrey
Ne vous inquiétez pas, à l'aide de
RandomAccessFile
pour accéder à un canal nommé est correct. Un tube nommé est un objet de système de fichiers. Sous Linux/Unix, il est aussi appelé "fifo". Ces objets sont lisibles comme un fichier. (et pas le même que les tuyaux utilisés entre les processus qui sont captées par l'Java Tuyau de classe).Cependant, je vois deux problèmes avec votre programme. Je ne peux pas tester actuellement c'est que j'aurais besoin de votre serveur de test (n'hésitez pas à publier). Votre lecteur thread attend des réponses de l'autre côté (c'est à dire le serveur). Il utilise readLine(), je voudrais utiliser une méthode différente (pour le débogage de lecture char par char peut être le meilleur).
Avec Java (sans JNI) vous ne pouvez pas créer un tube nommé (côté serveur). L'ouverture d'un tube nommé par le générique de la méthode utilisée par RandomAccessFile vous obtiendrez un octet de type de flux qui peut être simple ou duplex.
BTW: JTDS (la libre pilote JDBC SQL Server) peut éventuellement utiliser un pipe nommé pour accéder à SQL server, même sur le réseau. Et c'est en utilisant exactement le
RandomAccessFile
méthode.BTW2: il y a un makepipe.exe serveur de test sur les anciens MS SQL Server support d'installation, cependant, je ne les trouvez pas une source fiable pour obtenir ce fichier.
Vous ne pouvez pas le faire à accès aléatoire (seulement passer bien sûr), mais encore la classe est le seul à lire et à écrire à partir d'un tube nommé.
OriginalL'auteur
Je ne suis pas familier avec JAVA, et mon C# est assez élémentaire. Cependant, j'ai eu un problème similaire avec un multithread C++ client que j'ai corrigé par l'ouverture du canal pour se chevauchaient IO. Jusqu'à ce que j'ai fait cela, Windows sérialisé lit et écrit, efficacement, causant un insatisfait (blocage) ReadFile pour empêcher l'achèvement d'une WriteFile jusqu'à ce que la lecture a été faite.
Voir La fonction CreateFile
FILE_FLAG_OVERLAPPED
OriginalL'auteur StanBell