Jaka jest różnica między programem Reader a InputStream? A kiedy czego użyć? Jeśli mogę używać programu Reader do czytania znaków, dlaczego będę używał strumienia wejściowego, chyba do czytania obiektów?
87
Jaka jest różnica między programem Reader a InputStream? A kiedy czego użyć? Jeśli mogę używać programu Reader do czytania znaków, dlaczego będę używał strumienia wejściowego, chyba do czytania obiektów?
Odpowiedzi:
InputStream to surowa metoda uzyskiwania informacji z zasobu. Przechwytuje dane bajt po bajcie bez wykonywania jakiegokolwiek tłumaczenia. Jeśli czytasz dane obrazu lub dowolny plik binarny, jest to strumień, którego należy użyć.
Czytnik jest przeznaczony do strumieni znaków. Jeśli czytane informacje to cały tekst, to Czytelnik zajmie się dekodowaniem znaków za Ciebie i da Ci znaki Unicode z surowego strumienia wejściowego. Jeśli czytasz dowolny typ tekstu, to jest strumień, którego należy użyć.
Możesz opakować InputStream i przekształcić go w czytnik przy użyciu klasy InputStreamReader.
Reader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
źródło
InputStreams są używane do odczytywania bajtów ze strumienia. Są więc przydatne w przypadku danych binarnych, takich jak obrazy, wideo i zserializowane obiekty.
Z drugiej strony czytniki są strumieniami znaków, więc najlepiej nadają się do odczytu danych znakowych.
źródło
read()
bajtu po bajcie, a kiedyread(byte[])
tablicy bajtów. Myślę, że tablica czytania jest zawsze lepsza. to czy możesz mi podać przykład, gdzie używaćread()
bajt po bajcie LUBread(byte[])
tablicy bajtów. LUBBufferedInputStream
.?Myślę, że źródłem nieporozumień jest to, że
InputStream.read()
zwraca an,int
aReader.read()
także zwracaint
.Różnica polega na tym, że
InputStream.read()
zwracają wartości bajtów z zakresu od 0 do 255 odpowiadające surowej zawartości strumienia bajtów iReader.read()
zwracają wartość znaku mieszczącą się w zakresie od 0 do 65357 (ponieważ istnieje 65358 różnych punktów kodowych Unicode)InputStream
Pozwala odczytać zawartość bajt po bajcie, na przykład zawartość „A ‡ A” są odczytywane jako strumień bajtów (5 każdego reprezentowanego jakoint
przedziału od 0 do 255) powodując97
,226
,128
,161
i97
gdziea -> U+0061 -> 0x61 (hex) -> 97 (dec) ‡ -> U+2021 -> 0xE280A1 (utf-8 encoding of 0x2021) -> 226 128 161 (1 int per byte) a -> U+0061 -> 0x61 (hex) -> 97 (dec)
Reader
Pozwala odczytać znak po znaku zawartości więc zawartość „a ‡ A” są odczytywane jako 3 znaki97
,8225
i97
gdziea -> U+0061 -> 0x61 -> 97 ‡ -> U+2021 -> 0x2021 -> 8225 (single int, not 3) a -> U+0061 -> 0x61 -> 97
Znak ‡ jest określany jako U + 2021 w Unicode
źródło
Tło InputStream i Reader:
We wczesnych latach javy jedynym sposobem wykonywania danych wejściowych konsoli było użycie strumienia bajtów (InputStream i OutputStream).
Przypadków użycia:
Obecnie użycie strumienia bajtów do odczytu strumienia konsoli jest również dopuszczalne. Jednak w przypadku zastosowań komercyjnych preferowaną metodą odczytu danych wejściowych konsoli jest użycie strumienia zorientowanego znakowo (Reader). Czytnik ułatwia umiędzynarodowienie i utrzymanie.
Uwaga: To jest tylko dodatkowa informacja dotycząca eksploracji kodów we / wy Java. Wzorzec projektowy implementacji we / wy Java jest zgodny ze wzorcem projektowym dekoratora. Jeśli znasz wzorzec projektowy dekoratora, możesz łatwo nadrobić zaległości w realizacji.
źródło
Jeden akceptuje bajty, a drugi akceptuje znaki.
źródło
InputStream akceptuje bajt , Reader akceptuje znak, w Javie jeden znak = dwa bajty, a czytnik używa bufora, InputStream nie używa. Wszystkie pliki są przechowywane na dysku lub przesyłane w oparciu o bajty, zawierają obraz i wideo, ale znak jest w pamięci, więc InputStream jest często używany.
źródło