Czytając n bajtów atomowo bez blokowania

głosy
0

Ja po prostu zadał pytanie, dlaczego mój wątek shut down nie działa. Skończyło się to ze względu na readLine()zablokowanie mojego wątku przed flaga zamknięcie mogło być rozpoznane. To było łatwe do naprawienia poprzez sprawdzenie ready()przed wywołaniem readLine().

Jednak jestem teraz za pomocą DataInputStreamwykonać następujące czynności w serii:

int x = reader.readInt();
int y = reader.readInt();
byte[] z = new byte[y]
reader.readFully(z);

Wiem, że mogę realizować moje własne buforowanie co sprawdzić flagę z systemem plików podczas ładowania się bufor. Ale wiem, że to byłoby uciążliwe. Zamiast tego mogę pozwolić dane być buforowane w InputStreamklasie, i czekać, aż mam moje nbajtów czytać, przed wykonaniem non-blocking czytać - jak wiem, ile muszę czytać.

  • 4 bajtów dla liczby całkowitej
  • 4 bajty dla drugiej liczby całkowitej y
  • i ybajty na ztablicy bajtów.

Zamiast używać ready()do sprawdzenia, czy istnieje linia w buforze, czy istnieje jakiś odpowiednik ready(int bytesNeeded)?

Utwórz 13/02/2020 o 22:00
źródło użytkownik
W innych językach...                            


3 odpowiedzi

głosy
0

available()Sposób powraca do ilości bajtów w InputStreams bufora wewnętrznego.

Tak, można zrobić coś takiego:

while (reader.available() < 4) checkIfShutdown();
reader.readInt();
Odpowiedział 13/02/2020 o 22:19
źródło użytkownik

głosy
0

Można użyć InputStream.available(), aby uzyskać szacunkową ilość bajtów, które można odczytać. Cytując ten Javadoc :

Zwraca oszacowanie liczby bajtów, które można odczytać (lub pomijane) z tego strumienia wejściowego bez blokowania, który może być 0 lub 0, gdy zostanie wykryty koniec strumienia. Odczyt może być w tym samym wątku lub innego wątku. Pojedynczy odczyt lub pominięcie od tylu bajtów nie zablokuje, ale może czytać lub pominąć mniej bajtów.

Innymi słowy, jeśli available()wróci n, wiesz, że możesz bezpiecznie dzwonić read(n)bez blokowania. Należy zauważyć, że, jak twierdzi javadoc, zwracana wartość jest wartością szacunkową. Na przykład, InflaterInputStream.available () zawsze zwraca wartość 1, jeśli nie zostanie osiągnięta EOF. Sprawdź dokumentację InputStreampodklasy, która będzie używana w celu zapewnienia, że spełnia Twoje potrzeby.

Odpowiedział 13/02/2020 o 22:20
źródło użytkownik

głosy
0

Będziesz musiał zaimplementować własny odpowiednik BufferedInputStream. Albo jako jedynego właściciela InputStreami gwintem (ewentualnie pożyczonej od puli), aby zablokować w. Alternatywnie, zrealizować przy NIO.

Odpowiedział 13/02/2020 o 22:51
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more