2013-12-18 19 views
5

Zawsze zastanawiałem się: jaki jest koniec strumienia?Strumień wejścia/wyjścia: Koniec strumienia?

W javadoc większości metod readLine w pakiecie java.io, można przeczytać, że "to zwraca wartość null, jeśli osiągnięty został koniec strumienia" - chociaż nigdy nie uzyskałem wartości null, jak większość strumieni (w w przypadku strumienia sieciowego, którego używam najczęściej) po prostu zablokuj wykonanie programu, dopóki coś nie zostanie zapisane w strumieniu na zdalnym końcu.

Czy istnieją metody egzekwowania tego konkretnego zachowania w sposób nie rzucający wyjątków? Jestem po prostu ciekawy ...

+0

Odczytuje plik z FileInputStream. –

+0

Wymusić dokładnie to zachowanie? Chcesz zablokować program, dopóki coś innego nie będzie dostępne? –

+0

Powoduje, że program Reader zwraca wartość null podczas odczytu ze strumienia sieciowego za pomocą metody readLine(); – salbeira

Odpowiedz

8

Pomyśl o czytaniu pliku. Tam jest koniec strumienia, koniec pliku. Jeśli spróbujesz przeczytać coś więcej, po prostu nie możesz. Jeśli jednak masz połączenie sieciowe, nie musisz kończyć strumienia, jeśli po prostu czekasz na wysłanie większej ilości danych.

W przypadku pliku wiemy, że nie ma już danych do odczytania. W przypadku strumienia sieciowego (zwykle) nie.

Blokowanie FileReader gdy nie będzie dostępnych więcej danych, przebudzenie, gdy istnieje: odpowiedź jest prosta: nie można. Podstawową różnicą jest to, że czytasz plik aktywnie, ale kiedy słuchasz strumienia sieciowego, czytasz biernie. Kiedy coś pochodzi z sieci, twój sprzęt wysyła sygnał do systemu operacyjnego, który następnie przekazuje nowe dane do maszyny JVM, a następnie JVM budzi proces, aby odczytać nowe dane (że tak powiem). Ale nie mamy tego z plikiem, przynajmniej nie od razu.

Możliwe obejście polega na utworzeniu opakowania dla posiadanego StreamReader, z detektorem, który jest powiadamiany, gdy plik zostanie zmieniony, a następnie budzi się do dalszego czytania. W Javie 7 możesz użyć WatchService.

+0

Rzeczywiście udało mi się doprowadzić czytelnika do zwrócenia wartości zerowej poprzez zamknięcie gniazda na końcu zdalnym - oczywiście strumień jest kończony, ale jest również ustawiany wskaźnik informujący, że cokolwiek próbuje odczytać z niego, że dosłownie się zakończyło (aby odebrać dane) ... To jest moment, w którym czekałem na wstawienie kodu czyszczącego, gdy zdalny koniec zamknie połączenie! – salbeira

+0

Możesz sprawdzić ['configureBlocking'] (http://docs.oracle.com/javase/7/docs/api/java/nio/channels/spi/AbstractSelectableChannel.html#configureBlocking (boolean)) i [' available' ] (http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html # available()) –

0

W pewnym momencie gniazdo zostanie zamknięte i nie będzie można wysłać więcej danych za pośrednictwem tego strumienia. To wtedy InputStream zasygnalizuje EOF, zwracając -1 z read() i jego przeciążenia. Ten stan jest nieodwracalny. Ten strumień jest martwy.

Po prostu blokowanie większej ilości danych w otwartym strumieniu nie jest warunkiem EOF.

+0

Jaka jest dokładna różnica między EOF i EOS (tream)? - Odpowiedź taka jak "kod znaku" jest również ważna – salbeira

+0

@salbeira Nie ma różnicy i żadne dane nie są faktycznie przesyłane przez strumień (lub odczytane z pliku). Ten wynik jest generowany przez klasę implementacji 'InputStream'. To wynik logiki, nie jest to sygnał wewnątrzpasmowy. – erickson

1

nigdy faktycznie ma wartość null, ponieważ większość strumieni (w przypadku strumienia sieciowego, który używam najczęściej) tylko blokować wykonywanie programu aż coś jest napisane do strumienia na odległym końcu

Nie. Nigdy nie masz wartości zerowej, ponieważ urządzenie równorzędne nigdy nie zamknęło połączenia. To właśnie oznacza "koniec strumienia". Nie oznacza to "braku danych na razie".