2009-06-25 12 views
7

Próbuję odbierać strumień zdarzeń XML przez kanał Java NIO. Jestem nowy zarówno dla NIO, jak i StAXa, więc mogłem z łatwością coś przeoczyć :)Przetwarzanie StAX z kanału Java NIO

Moje poszukiwania doprowadziły mnie do kilku implementacji SAX i StAX, ale wszystkie działają na InputStreams i InputSources - nie NIO kanały. Dwa najbliższe próby Mam wykonane zostały uzyskać InputStream z kanału i stworzyć PipedInputStream:

// method 1 
PipedOutputStream out = new PipedOutputStream(); 
InputStream in = new PipedInputStream(out); 
PrintWriter writer = new PrintWriter(out); 

//method 2 
InputStream in = channel.socket().getInputStream() 
//method 3 
IputStream in = Channels.newInputStream(channel); 

następuje:

XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance() 
     .createXMLStreamReader(in); 
//... 

Kiedy powyższy kod jest używany z metody 1, bloków w linii createXMLStreamReader. Kiedy metody 2/3 są używane, natychmiast rzucają IllegalBlockingModeException (rozumiem dlaczego). Może potrzebne jest nowe podejście?

Moim celem jest posiadanie niezablokowanego serwera select => akceptuj dane znakowe od klienta => parsuj go do zdarzeń XML za pomocą określonego kodowania => przekazuj ten obiekt zdarzenia do innego wątku w celu przetworzenia => i wróć do wybór.

Więc coś przeoczyłem, czy istnieje lepsze podejście, które można wykorzystać? Jeśli tak to co?

Dzięki!

+0

Tak jak wspomniany Fern, procesor Aalto xml ma tryb asynchroniczny, który jest przeznaczony do takich przypadków użycia. Nie było zbyt dużego zainteresowania (nie wiele systemów opartych na NIO ... jeszcze) na tryb asynchroniczny - wszyscy dotychczasowi użytkownicy wydają się używać BIO - ale w rzeczywistości byłoby to bardzo dobre dopasowanie. – StaxMan

+0

I wreszcie z wersją 0.9.7, jest trochę dokumentacji, aby pokazać, jak nie blokować analizy, zobacz: http://www.cowtowncoder.com/blog/archives/2011/03/entry_451.html – StaxMan

Odpowiedz

4

Czy na pewno chcesz korzystać z NIO? To może nie oferować względne korzyści pierwotnie spodziewanych:

Paweł Tyma: Kill the myth please. NIO is not faster than IO

Paweł Tyma: Writing Java Multithreaded Servers - whats old is new

Stos pokazując gdzie wewnątrz createXMLStreamReader() jest blokowanie może pomóc, ale to pewnie zachowuje się zgodnie z przeznaczeniem . Jeśli został zaprojektowany do pracy z InputStreams, który zawsze albo (1) podaje oczekiwaną ilość danych; (2) koniec; lub (3) blokuje, a następnie nie zachowa się automatycznie w (zwykle bardziej skomplikowanym i stanowym) sposobie, który może powrócić po odczytaniu dowolnej ilości niekompletnych danych wejściowych, bez wielu głębokich przeróbek.

+1

+1 - dość otwarcie oczu. –

+0

NIO nie ma większej przepustowości niż domyślne operacje wejścia/wyjścia. Ale to * może * być. – Renascienza

0

Należy użyć klasy narzędzia java.nio.channels.Channels.

ReadableByteChannel ch = //... 
InputStream in = Channels.newInputStream(ch); 

Być może konieczne będzie skonfigurowanie kanału gniazda do blokowania.

SelectableChannel ch = //... 
ch.configureBlocking(true); 

Oznacza to, że nie będzie można wykonywać nieblokujących wejść/wyjść.

+0

PO już to wypróbował (patrz metoda 3) . – skaffman

+0

Tak, zauważyłem, że po opublikowaniu dodałem wywołanie configureBlocking, które powinno naprawić metodę 3. –

+0

Problem z blokowaniem polega na tym, że próbuję nie mieć wątku na połączenie, ale raczej pojedynczy wątek odczytany, a następnie rozwidlenie dodatkowe przetwarzanie w razie potrzeby –

2

Zacząłem też rozglądać się, także w przypadku używania serwera XMPP. Rozglądałem się i wygląda na to, że jest tylko jedna implementacja, która obiecuje wsparcie NIO: Aalto http://wiki.fasterxml.com/AaltoHome

Ale wydaje się, że wypuściła wersję 0.9.5, marzec 2009. Tak więc, nie jestem pewien jak dobrze utrzymuje, ale to może być dobry punkt wyjścia. Chyba, że ​​uda ci się przekonać większy projekt (może Woodstox), aby przerobić niektóre z ich klas wewnętrznych na wsparcie NIO.

+0

Szybki komentarz: chociaż może nie być oczywiste ze strony Aalto, jego baza programistów znacznie się pokrywa z Woodstox. Częściowo jest tak, że wewnętrzna część Aalto jest bardzo różna i niełatwo sprawić, by systemy oparte na BIO działały na NIO. Aalto, z drugiej strony, bardzo dobrze pasuje do NIO - ma tryb asynchroniczny, który choć nieco niekompletny (API nie do końca zdefiniowany), jest dość zbliżony do produkcji gotowej. Jeśli więc ktoś jest zainteresowany, zachęcamy do przyłączenia się do forum dyskusyjnego Aalto - programiści (w tym ja) chcieliby zobaczyć więcej uczestnictwa. – StaxMan