Главная страница
Навигация по странице:

  • System.in, System.out

  • 5 блок. Вводвывод, доступ к файловой системе


    Скачать 270.29 Kb.
    Название5 блок. Вводвывод, доступ к файловой системе
    Дата03.09.2022
    Размер270.29 Kb.
    Формат файлаdocx
    Имя файлаJava 5 module.docx
    ТипДокументы
    #660115
    страница2 из 3
    1   2   3
    1   2   3

    22. Какие есть методы у класса OutputStream ? (5 штук)

    - void close(): закрывает поток.

    - void flush(): очищает буфер вывода, записывая все его содержимое.

    - void write(int b): записывает в выходной поток один байт, который представлен целочисленным параметром b.

    - void write(byte[] buffer): записывает в выходной поток массив байтов buffer.

    - void write(byte[] buffer, int offset, int length): записывает в выходной поток некоторое число байтов, равное length, из массива buffer, начиная со смещения offset, то есть с элемента buffer[offset].

    23. Какие есть подклассы у класса Reader? (10 штук)

    - Reader() - абстрактный класс, описывающий символьный ввод;

    - BufferedReader() - буферизованный входной символьный поток;

    - CharArrayReader() - входной поток, который читает из символьного массива;

    - FileReader() - входной поток, читающий файл;

    - FilterReader() - абстрактный класс, предоставляющий интерфейс для классов-надстроек;

    - InputStreamReader() - входной поток, транслирующий байты в символы;

    - LineNumberReader() - входной поток, подсчитывающий строки;

    - PipedReader() - входной канал;

    - PushbackReader() - входной поток, позволяющий возвращать символы обратно в поток;

    - StringReader() - входной поток, читающий из строки.

    24. Какие есть методы у класса Reader? (6 штук)

    - absract void close(): закрывает поток ввода

    - int read(): возвращает целочисленное представление следующего символа в потоке. Если таких символов нет, и достигнут конец файла, то возвращается число -1

    - int read(char[] buffer): считывает в массив buffer из потока символы, количество которых равно длине массива buffer. Возвращает количество успешно считанных символов. При достижении конца файла возвращает -1

    - int read(CharBuffer buffer): считывает в объект CharBuffer из потока символы. Возвращает количество успешно считанных символов. При достижении конца файла возвращает -1

    - absract int read(char[] buffer, int offset, int count): считывает в массив buffer, начиная со смещения offset, из потока символы, количество которых равно count

    - long skip(long count): пропускает количество символов, равное count. Возвращает число успешно пропущенных символов

    25. Почему метод read() возвращает int а не byte?

    Возвращается int, потому что нужен такой тип, который может вместить в себя один байт (реальные данные) плюс одно служебное значение (это тот самый -1), которое является признаком окончания чтения.

    25. Какие есть подклассы у класса Writer? (9 штук)

    - Writer() - абстрактный класс, описывающий символьный вывод;

    - BufferedWriter() - буферизованный выходной символьный поток;

    - CharArrayWriter() - выходной поток, который пишет в символьный массив;

    - FileWriter() - выходной поток, пишущий в файл;

    - FilterWriter() - абстрактный класс, предоставляющий интерфейс для классов-надстроек;

    - OutputStreamWriter() - выходной поток, транслирующий байты в символы;

    - PipedWriter() - выходной канал;

    - PrintWriter() - выходной поток символов, включающий методы print() и println();

    - StringWriter() - выходной поток, пишущий в строку;

    26. Какие есть методы у класса Writer? (9 штук)

    - Writer append(char c): добавляет в конец выходного потока символ c. Возвращает объект Writer

    - Writer append(CharSequence chars): добавляет в конец выходного потока набор символов chars. Возвращает объект Writer

    - abstract void close(): закрывает поток

    - abstract void flush(): очищает буферы потока

    - void write(int c): записывает в поток один символ, который имеет целочисленное представление

    - void write(char[] buffer): записывает в поток массив символов

    - absract void write(char[] buffer, int off, int len) : записывает в поток только несколько символов из массива buffer. Причем количество символов равно len, а отбор символов из массива начинается с индекса off

    - void write(String str): записывает в поток строку

    - void write(String str, int off, int len): записывает в поток из строки некоторое количество символов, которое равно len, причем отбор символов из строки начинается с индекса off

    27. Паттерн адаптер

    Паттерн — это шаблон, решение общих проблем проектирования. Паттерны решают ряд основных проблем, связанных с программированием/проектированием. Это — изобретение велосипеда, проблема повторного использования кода, проблема сопровождения кода.
    Преобразует интерфейс одного класса в интерфейс того класса, который нужен клиенту.

    Используется для обеспечения совместной работы классов, интерфейсы которых не совместимы

    Пример использования:

    - Интерфейс класса, который мы хотим использовать не соответствует нашим потребностям

    - Нужен класс, умеющий взаимодействовать с классами, которые ему неизвестны, или не связаны с ним.

    - Нужно использовать несколько существующих подклассов, но целесообразно использовать методы этих классов создавая их новые подклассы.
    Паттерн Адаптер организовывает использование функций объекта, недоступного для модификации, через специально созданных интерфейс.

    Адаптер нужен для того, чтобы наделить определённым интерфейсом класс недоступный для модификации, при помощи отдельного класса (обёртка) адаптера.

    Есть два способа организовать адаптер, через класс и через экземпляр.

    Применяется паттерн в случае:

    - Когда необходимо использовать имеющийся класс, но его интерфейс не соответствует потребностям.

    - Когда надо использовать уже существующий класс совместно с другими классами, интерфейсы которых не совместимы.

    Пример кода можно посмотреть тут!

    28. Паттерн декоратор?

    Декоратор — это структурный паттерн проектирования, который позволяет динамически добавлять объектам новую функциональность, оборачивая их в полезные «обёртки».

    Любая одежда — это аналог Декоратора. Применяя, Декоратор, вы не меняете первоначальный класс и не создаёте дочерних классов.
    Примеры Декораторов в стандартных библиотеках Java:

    - Все подклассы java.io.InputStream, OutputStream, Reader и Writer имеют конструктор, принимающий объекты этих же классов.

    - java.util.Collections, методы checkedXXX(), synchronizedXXX() и unmodifiableXXX().

    - javax.servlet.http.HttpServletRequestWrapper и HttpServletResponseWrapper.
    Признаки применения паттерна: Декоратор можно распознать по создающим методам, которые принимают в параметрах объекты того же абстрактного типа или интерфейса, что и текущий класс.

    29. Отличия Адаптера и Декоратора?

    Декоратор (Wraper) позволяет создать цепочку обёрток, и каждая обёртка добавляет что-то к исходному объекту. Обогащает его функционал. Было побайтовое чтение, раз и добавили обёрткой буферизацию, а потом еще что-нибудь... и т.д.
    Адаптер - посредник, переходник. Например, конвертировать данные одного формата в другой формат, чтобы две независимые библиотеки могли договориться друг с другом (например, XML и JSON).

    28. Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?

    - OutputStreamWriter() — «мост» между классом OutputStream и классом Writer. Символы, записанные в поток, преобразовываются в байты.

    - InputStreamReader() — аналог для чтения. При помощи методов класса Reader читаются байты из потока InputStream и далее преобразуются в символы.

    29. Какие классы позволяют ускорить чтение/запись за счет использования буфера?

    - BufferedInputStream()

    - BufferedOutputStream()

    - BufferedReader()

    - BufferedWriter()

    30. Классы BufferedReader и BufferedWriter, и их отличия от стримов.

    Все буферы расширяют стримы. (кстати это пример применения паттерна Декоратора).

    Эти классы предназначены для предварительной буферизации записываемых символов, тем самым снижают количество обращений к физическому носителю для записи/чтения данных и ускоряют процесс записи/чтения файла.

    Чтение данных с диска byte-by-byte очень неэффективно. Один из способов ускорить это - использовать буфер: вместо того, чтобы читать по одному байту за раз, Вы читаете несколько тысяч байтов одновременно и помещаете их в буфер, в память. Затем вы можете посмотреть на байты в буфере один за другим.
    BufferedReader читает текст из потока ввода символов, буферизуя прочитанные символы, чтобы обеспечить эффективное считывание символов, массивов и строк.

    BufferedReader имеет два конструктора:

    - BufferedReader(Reader in) // Создает буферный поток ввода символов, использует размер буфера по умолчанию.

    - BufferedReader(Reader in, int sz) // Создает буферный поток ввода символов, который использует указанный размер.
    Java класс BufferedWriter (тоже имеет два конструктора) записывает текст в поток вывода символов, буферизуя записанные символы, чтобы обеспечить эффективную запись символов, массивов и строк. Аналогично имеет два конструктора.
    FileWriter сразу записывает данные на диск и каждый раз к нему обращается, буфер работает как обёртка и ускоряет работу приложения. Буфер будет записывать данные в себя, а потом большим куском файлы на диск.

    31. Методы класса BufferedReader?

    - close() // закрыть поток

    - mark(int readAheadLimit) // отметить позицию в потоке

    - markSupported() // поддерживает ли отметку потока

    - int read() // прочитать буфер

    - int read(char[] cbuf, int off, int len) // прочитать буфер

    - String readLine() // читает данные построчно

    - boolean ready() // может ли поток читать

    - reset() // сбросить поток

    - skip(long n) // пропустить символы

    32. Методы класса BufferedWriter ?

    - close() // закрыть поток

    - flush() // передать данные из буфера во Writer

    - newLine() // перенос на новую строку

    - write(char[] cbuf, int off, int len) // запись в буфер

    - write(int c) // запись в буфер

    - write(String s, int off, int len) // запись в буфер

    33. Что делает flush? Выполнится ли flush если мы сделаем close у потока?

    void flush () – Очищает выходной поток и заставляет записывать все буферизованные выходные байты.

    Если какие-либо ранее записанные байты были буферизованы реализацией выходного потока, такие байты должны быть немедленно записаны в их предполагаемое место назначения.

    Находится в интерфейсе Flushable.

    34. Как работает сам close()? Что и зачем нужно закрывать?

    Записывает в целевой объект все незаписанные данные и закрывает этот выходной поток и освобождает все системные ресурсы, связанные с этим потоком.

    В случае, если поток окажется не закрыт, может происходить утечка памяти.

    35. Можно ли flush() применить для небуферизированного потока и что будет?

    Буферизация в основном выполняется для повышения производительности ввода-вывода.

    flush() нельзя применить для небуферизированного потока. А если и применить, то ничего не произойдёт.

    System.in, System.out?

    1. Что такое System.in, что такое System.out, и причём здесь Scanner?

    System — это последний класс из пакета java.lang.

    out — это переменная класса типа PrintStream, объявленная в классе System.

    In - это переменная класса типа InputStream, объявленная в классе System.

    println - метод класса PrintStream.

    Для работы с потоком ввода необходимо создать объект класса Scanner, при создании указав, с каким потоком ввода он будет связан. Стандартный поток ввода (с клавиатуры) в Java представлен объектом — System.in. А стандартный поток вывода (дисплей) —объектом System.out. Есть ещё стандартный поток для вывода ошибок — System.err.

    2. Методы класса Scanner?

    - next(): считывает введённую строку до первого пробела

    - nextLine(): считывает всю введенную строку

    - nextInt(): считывает введенное число int

    - nextDouble(): считывает введенное число double

    - nextBoolean(): считывает значение boolean

    - nextByte(): считывает введенное число byte

    - nextFloat(): считывает введенное число float

    - nextShort(): считывает введенное число short

    3. Что такое токен в Scanner?

    Токен (или маркер) представляет собой серию цифровых или буквенно-цифровых символов, которая заканчивается разделителем. Разделителем может быть символ табуляции, возврат каретки (перевод строки или же просто 'Enter'), конец файла или пробел.

    3. Отличия Scanner и BufferedReader, когда использовать тот и другой?

    - BufferedReader имеет значительно большую буферную память, чем сканер. Используйте BufferedReader , если вы хотите получить длинные строки из потока, и используйте Scanner, если вы хотите проанализировать определенный тип токена из потока.

    - Scanner может использовать токенизацию с помощью пользовательского разделителя и разбирать поток на примитивные типы данных, в то время как BufferedReader может только читать и хранить строку.

    - BufferedReader является синхронным, а Scanner -нет. Используйте BufferedReader , если вы работаете с несколькими потоками.

    - Scanner прячет IOException, в то время как BufferedReader немедленно бросает его.

    - Можно передать BufferedReader в Scanner в качестве источника символов для синтаксического анализа.

    4. В каких случаях использовать Reader и Scanner?

    Scanner предназначен для разбора любого текста и, ввода с терминала, как частный случай. Он умеет выцеживать числа всякие и т.п. Удобен для простого разбора текстов и для всяких учебных задачек типа "введите число от нуля до трёх".
    BufferedReader нужен, чтобы буферизовать чтение с любого потока. Как частный случай, можно буферизовать ввод с терминала. Иногда используется ради метода readLine, когда сложно или просто день обрабатывать текст блоками. Для целей чтения текста из стандартного вводы или ручного ввода пользователя вполне пригодный вариант. Но при таком подходе придётся парсить числа вручную, что не слишком большая сложность.

    5. Есть ли у сканера буфер? (да)

    Scanner имеет меньший буфер ( 1024 символа ) в отличие от BufferedReader ( 8192 символа).

    IO и NIO

    1. Основные отличия пакетов IO и NIO



    Java NIO позволяет управлять несколькими каналами (сетевыми соединениями или файлами) используя минимальное число потоков выполнения. Однако ценой такого подхода является более сложный, чем при использовании блокирующих потоков, парсинг данных.
    Если вам необходимо управлять тысячами открытых соединений одновременно, причем каждое из них передает лишь незначительный объем данных, выбор Java NIO для вашего приложения может дать преимущество.

    Подробнее можно почитать тут!
    ///////////////// class io

    InputStream inputStreamIO = new FileInputStream("c:\\input.txt");

    OutputStream outputStreamIO = new FileOutputStream("c:\\output.txt");

    //////////////////class nio

    InputStream inputStreamNIO = Files.newInputStream(Paths.get("c:\\input1.txt"));

    OutputStream outputStreamNIO = Files.newOutputStream(Paths.get("c:\\output.txt"));

    2. Потокоориентированный и буфер-ориентированный ввод/вывод?

    - Потокоориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно. Данная информация нигде не кэшируются. Таким образом, невозможно произвольно двигаться по потоку данных вперед или назад. Если вы хотите произвести подобные манипуляции, вам придется сначала кэшировать данные в буфере.
    - Подход, на котором основан Java NIO немного отличается. Данные считываются в буфер для последующей обработки. Вы можете двигаться по буферу вперед и назад. Это дает немного больше гибкости при обработке данных. В то же время, вам необходимо проверять содержит ли буфер необходимый для корректной обработки объём данных. Также необходимо следить, чтобы при чтении данных в буфер вы не уничтожили ещё не обработанные данные, находящиеся в буфере.


    3. Блокирующий и неблокирующий ввод/вывод?

    Потоки ввода/вывода (streams) в Java IO являются блокирующими. Это значит что, когда в потоке выполнения (tread) вызывается read() или write() метод любого класса из пакета java.io.*, происходит блокировка до тех пор, пока данные не будут считаны или записаны. Поток выполнения в данный момент не может делать ничего другого.
    Неблокирующий режим Java NIO позволяет запрашивать считанные данные из канала (channel) и получать только то, что доступно на данный момент, или вообще ничего, если доступных данных пока нет. Вместо того, чтобы оставаться заблокированным пока данные не станут доступными для считывания, поток выполнения может заняться чем-то другим.

    Таким образом неблокирующий режим Java NIO позволяет использовать один поток выполнения для решения нескольких задач вместо пустого прожигания времени на ожидание в заблокированном состояний. Наиболее частой практикой является использование сэкономленного времени работы потока выполнения на обслуживание операций ввода/вывода в другом или других каналах.

    4. Что такое селекторы?




    Селекторы в Java NIO позволяют одному потоку выполнения мониторить несколько каналов ввода. Вы можете зарегистрировать несколько каналов с селектором, а потом использовать один поток выполнения для обслуживания каналов, имеющих доступные для обработки данные, или для выбора каналов, готовых для записи.




    написать администратору сайта