2011-12-13 8 views
9

Czy znasz sposób przerwania odczytu z Javy InputStream bez zamykania powiązanego gniazda?Jakikolwiek sposób użycia pliku java.nio. * Do przerwania metody InputStream # read() bez zamykania gniazda?

Tutaj jest obecny strategia budowy do przechwytywania strumienia wejściowego gniazda i konwersji do przerywanej DataInputStream:

InputStream interruptibleInputStream = Channels.newInputStream(Channels.newChannel(m_ConnectionData.getSocket().getInputStream())); 
DataInputStream myInterruptibleDIS = new DataInputStream(interruptibleInputStream); 

Dzięki zastosowanie ReadableByteChannel który oferuje metodę read(ByteBuffer) obsługującą ClosedByInterruptException ratunkowym.

Problem polega na tym, że wywołanie przerwania w wątku wywołującym read() wywołania na DataInputStream powoduje zamknięcie podstawowego gniazda.

Dla mojego kontekstu potrzebuję gniazda do pozostania otwartym; wywołanie read oczekuje na dane wejściowe użytkownika, które nie nadchodzą, więc używam przerwania, aby przekazać sterowanie z powrotem do wyższego komponentu, a następnie ponownie powrócić do read ponownie.

Byłbym bardzo wdzięczny, gdyby ktoś mógł zaproponować sposób osiągnięcia tego przy użyciu wbudowanych klas JDK, lub może wskazać, że nie jest to możliwe z niektórymi informacjami.

Rozumiem, że istnieją inne sposoby osiągnięcia tego samego efektu, ale mimo to jestem ciekawy, czy takie podejście jest wykonalne.

+0

Możesz użyć 'Selector' i' .select (int) 'na gnieździe. – fge

+1

ustawić limit czasu odczytu na gnieździe. – jtahlborn

+0

@fge - Dziękuję. Zbadałem, co zasugerowałeś i wygląda to na wiarygodne. Więc jeśli uruchomię mySelector.select() w moim wątku zamiast read() bezpośrednio, a następnie przerwie wątek, gniazdo pozostanie otwarte? – KomodoDave

Odpowiedz

2

Jeśli przerwiesz przerwanie kanału podczas odczytu, zostanie on zamknięty i wygeneruje wyjątek ClosedByInterruptException. Jeśli chcesz po prostu przekroczyć limit czasu odczytu, nie używaj w ogóle kanału, tylko zwykłego gniazda; wywołaj Socket.setSoTimeout() z krótkim czasem oczekiwania i sprawdź status isInterrupted() wątku za każdym razem, gdy zostanie wyzwolony limit czasu. Lepiej, sprawdź swoje wymaganie, aby przerwać wątek. Po co to?

+0

Wielkie dzięki :-) – KomodoDave

Powiązane problemy