JavaRush /Blog Java /Random-PL /Przećwicz pracę z klasami BufferedReader i WejścieStreamR...

Przećwicz pracę z klasami BufferedReader i WejścieStreamReader

Opublikowano w grupie Random-PL
Cześć! Dzisiejszy wykład będzie podzielony na dwie części. Powtórzymy niektóre stare tematy, które już poruszaliśmy i przyjrzymy się kilku nowym funkcjom :) Poćwicz pracę z klasami BuffreredReader i WejścieStreamReader - 1Zacznijmy od pierwszego. Powtarzanie jest matką nauki :) Korzystałeś już z takich zajęć jak BufferedReader. Mam nadzieję, że nie zapomniałeś jeszcze tego polecenia:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Zanim zaczniesz czytać dalej, postaraj się zapamiętać System.in, InputStreamReader, BufferedReaderza co odpowiada każdy komponent ( ) i do czego jest potrzebny. Stało się? Jeśli nie, nie martw się :) Jeśli w tym momencie o czymś zapomniałeś, przeczytaj jeszcze raz ten wykład dedykowany czytelnikom. Przypomnijmy krótko, co każdy z nich może zrobić. System.into wątek do odbierania danych z klawiatury. W zasadzie do realizacji logiki czytania tekstu wystarczyłby nam jeden. Ale, jak pamiętasz, System.inmoże czytać tylko bajty, a nie znaki:
public class Main {

   public static void main(String[] args) throws IOException {

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
Jeśli uruchomimy ten kod i wpiszemy literę „Y” w konsoli, wynik będzie następujący:

Й
208
153
10
Znaki cyrylicy zajmują 2 bajty w pamięci, które są wyświetlane na ekranie (a liczba 10 to bajtowa reprezentacja podziału wiersza, czyli naciśnięcia Enter). Czytanie bajtów to wielka przyjemność, więc używanie go System.inw czystej postaci będzie niewygodne. Aby odczytać litery cyrylicy (i nie tylko) zrozumiałe dla każdego, używamy InputStreamReaderjako opakowania:
public class Main {

   public static void main(String[] args) throws IOException {

       InputStreamReader reader = new InputStreamReader(System.in);
       while (true) {
           int x = reader.read();
           System.out.println(x);
       }
   }
}
Jeśli w konsoli wpiszemy tę samą literę „Y”, wynik tym razem będzie inny:

Й
1049
10
InputStreamReaderskonwertował dwa odczytane bajty (208, 153) na pojedynczą liczbę 1049. Jest to czytanie znakowe. 1049 odpowiada literze „Y”, co można łatwo zweryfikować:
public class Main {

   public static void main(String[] args) throws IOException {

       char x = 1049;
       System.out.println(x);
   }
}
Wyjście konsoli:

Й
Cóż, jeśli chodzi o BufferedReader'a (i ogólnie - BufferedAnything), klasy buforowane służą do optymalizacji wydajności. Dostęp do źródła danych (pliku, konsoli, zasobu w Internecie) jest operacją dość kosztowną pod względem wydajności. Dlatego też, aby ograniczyć ilość takich połączeń, BufferedReaderodczytuje i gromadzi dane w specjalnym buforze, skąd możemy je później odebrać. W rezultacie liczba wywołań do źródła danych zmniejsza się kilkukrotnie, a nawet dziesięciokrotnie! Kolejną dodatkową cechą BufferedReader„a i jego przewagą nad zwykłym InputStreamReader” jest niezwykle przydatna metoda readLine(), która odczytuje dane jako całe ciągi znaków, a nie pojedyncze liczby. To oczywiście znacznie zwiększa wygodę przy implementowaniu np. dużego tekstu. Tak wyglądałoby czytanie wiersza:
public class Main {

   public static void main(String[] args) throws IOException {

       BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
       String s = reader.readLine();
       System.out.println("Пользователь ввел следующий текст:");
       System.out.println(s);
       reader.close();
   }
}

BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Пользователь ввел следующий текст:
BufferedReader+InputStreamReader работает быстрее, чем просто InputStreamReader
Poćwicz pracę z klasami BuffreredReader i WejścieStreamReader - 2Oczywiście BufferedReaderjest to bardzo elastyczny mechanizm i pozwala na pracę nie tylko za pomocą klawiatury. Dane możesz odczytać np. bezpośrednio z Internetu, po prostu przekazując do czytnika wymagany adres URL:
public class URLReader {
   public static void main(String[] args) throws Exception {

       URL oracle = new URL("https://www.oracle.com/index.html");
       BufferedReader in = new BufferedReader(
               new InputStreamReader(oracle.openStream()));

       String inputLine;
       while ((inputLine = in.readLine()) != null)
           System.out.println(inputLine);
       in.close();
   }
}
Możesz odczytać dane z pliku, przekazując do niego ścieżkę:
public class Main {
   public static void main(String[] args) throws Exception {

       FileInputStream fileInputStream = new FileInputStream("testFile.txt");
       BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));

       String str;

       while ((str = reader.readLine()) != null)   {
           System.out.println (str);
       }

       reader.close();
   }
}

Podstawienie System.out

Przyjrzyjmy się teraz jednej interesującej możliwości, o której wcześniej nie wspomnieliśmy. Jak zapewne pamiętasz, Systemw klasie znajdują się dwa pola statyczne - System.ini System.out. Ci bracia bliźniacy są obiektami klasy wątków. System.in- klasa abstrakcyjna InputStream. Klasa . System.out_ PrintStreamTeraz porozmawiamy konkretnie o System.out. Jeśli wejdziemy w kod źródłowy klasy System, zobaczymy to:
public final class System {

……………...

public final static PrintStream out = null;

  …………

}
A więc System.outzwykła zmienna klasy statycznejSystem . Nie ma w tym żadnej magii :) Zmienna outnależy do klasy PrintStream. Oto interesujące pytanie: dlaczego podczas wykonywania kodu System.out.println()dane wyjściowe pojawiają się w konsoli, a nie gdzie indziej? I czy da się to jakoś zmienić? Przykładowo chcemy odczytać dane z konsoli i zapisać je do pliku tekstowego. Czy można w jakiś sposób zaimplementować taką logikę bez użycia dodatkowych klas czytników i zapisów, ale po prostu używając System.out? Jeszcze jak najbardziej :) I chociaż zmienna System.outjest oznaczona modyfikatorem final, to i tak możemy to zrobić! Poćwicz pracę z klasami BuffreredReader i WejścieStreamReader - 3Czego więc potrzebujemy do tego? Po pierwsze , potrzebujemy nowego obiektu klasy PrintStreamzamiast obecnego. Aktualny obiekt zainstalowany w klasie Systemdomyślnie nam nie odpowiada: wskazuje na konsolę. Musimy stworzyć nowy, który będzie wskazywał plik tekstowy jako „miejsce docelowe” naszych danych. Po drugie , musisz zrozumieć, jak przypisać nową wartość do zmiennej System.out. Nie można tego tak po prostu zrobić, bo jest to oznaczone final. Zacznijmy od końca. Klasa Systemzawiera dokładnie taką metodę, jakiej potrzebujemy - setOut(). Przyjmuje obiekt jako wejście PrintStreami ustawia go jako punkt wyjściowy. Właśnie tego potrzebujemy! Pozostaje tylko stworzyć obiekt PrintStream. Jest to również łatwe do zrobienia:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
Cały kod będzie wyglądał następująco:
public class SystemRedirectService {

   public static void main(String arr[]) throws FileNotFoundException
   {
       PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));

       /*Сохраним текущее oznaczający System.out в отдельную переменную, чтобы потом
       можно было переключиться обратно на вывод в консоль*/
       PrintStream console = System.out;

       // Присваиваем System.out новое oznaczający
       System.setOut(filePrintStream);
       System.out.println("Эта строка будет записана в текстовый файл");

       // Возвращаем System.out старое oznaczający
       System.setOut(console);
       System.out.println("А эта строка - в консоль!");
   }
}
W rezultacie pierwsza linia zostanie zapisana do pliku tekstowego, a druga zostanie wysłana na konsolę :) Możesz skopiować ten kod do swojego IDE i uruchomić go. Otwierając plik tekstowy, zobaczysz, że żądana linia została tam pomyślnie wpisana :) Na tym kończy się wykład. Dziś przypomnieliśmy sobie jak pracować ze strumieniami i czytnikami, przypomnieliśmy czym się od siebie różnią i dowiedzieliśmy się o nowych funkcjach System.out, z których korzystaliśmy niemal na każdej lekcji :) Do zobaczenia na kolejnych wykładach!
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION