2012-02-29 16 views
5

Bardzo prosty problem: Czytam z jednego SocketChannel i chciałbym zapisać wyniki w innym SocketChannel. Używam obiektu Selector, więc czekam, aż jeden SocketChannel będzie czytelny, zrzuci dane do ByteBuffer, a kiedy następny SocketChannel będzie zapisywalny, zrzucę tam ByteBuffer. OK do tej pory. Jednak wydaje się, że nie ma sposobu, aby "wyczyścić" ByteBuffer, więc nie mogę sprawdzić, kiedy nadejdą nowe dane.Czyszczenie ByteBuffer

Próbowałem metody .clear(), ale to najwyraźniej nie czyści bufor, ale po prostu resetuje pozycję bufora na 1.

Nigdy programu w Javie więc urodziła się ze mną, jeśli jest to problem z roztworem "oczywiste" ...

Oto niektóre przykładowy kod:

ByteBuffer channel1buf = ByteBuffer.allocate(1024); 
ByteBuffer channel2buf = ByteBuffer.allocate(1024); 

if (key.isReadable()) { 
    if (key.channel().equals(channel1)) { 
     channel1.read(channel2buf); 
    } else if (key.channel().equals(channel2)) { 
     channel2.read(channel1buf); 
    } 
} else if (key.isWritable()) { 
    if (key.channel().equals(channel1) && channel1buf.asCharBuffer().length() > 0) { 
     channel1.write(channel1buf); 
     /* some way to clear channel1buf */ 
    } else /* same idea for channel2... */ 
} 

Dzięki!

+0

należy użyć 'ByteBuffer' jako załącznik podczas rejestracji kanału do selektora (trzeci parametr metody regsiter), w ten sposób można pobrać załącznik z' SelectionKey' i uniknąć wszystkich zagnieżdżonych jeśli klauzul . – mike

Odpowiedz

4

Buffer.clear resetuje pozycję, tak, a następnie można użyć getPosition() > 0, aby sprawdzić, czy wszystko zostało dodane do bufora, nie ...?

+0

To _almost_ działa, ale bufor nadal zawiera stare dane, więc wydrukuje wszelkie przepełnienia. Chyba mógłbym przejrzeć bufor i wyczyścić go ręcznie, ale to nie wydaje się zbyt eleganckie. – user1241397

+0

Chodzi o to, dlaczego obchodzi cię, czy bufor nadal zawiera stare dane? To nie tak, że usunięcie go da ci GC. Po prostu nie patrz na nic pod 'getPosition()' i powinieneś być w porządku ... czy jest coś czego mi brakuje? –

+0

Cóż, bufor ma pewną stałą wielkość, więc jeśli to zrobię, w końcu zabraknie mi miejsca w buforze. – user1241397

4

Rozwiązałem ten sam problem za pomocą tego kodu, mam nadzieję, że może ci pomóc.

channel1buf.clear(); 
//zerolize buff manually 
channel1buf.put(new byte[1024]); 
channel1buf.clear(); 
+1

Lub 'Arrays.fill (channel1buf, (byte) 0); channel1buf.clear(); ' –

+1

Ale ten rodzaj' ZeroMemory() 'dla bufora nie jest potrzebny, jeśli używasz klasy' ByteBuffer' w taki sposób, w jaki ma być używana, czyli przez wywołanie 'flip()' przed czytanie, 'rewind()' przed ponownym odczytaniem, 'clear()' lub 'compact()' przed zapisem. – Lumi