Файл: Потока. В данном случае мы будем говорить о потоке (stream), как об абстракции, которая используется для чтения или записи информации (файлов, сокетов, текста консоли и т д.). Объект, из которого можно считать данные, называется потоком ввода.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 04.12.2023

Просмотров: 71

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

1)
Что такое потоки ввода-вывода? Как это реализовано в Java?
В Java основной функционал работы с потоками сосредоточен в классах из пакета java.io. Ключевым понятием здесь является понятие потока. В данном случае мы будем говорить о потоке (stream), как об абстракции, которая используется для чтения или записи информации (файлов, сокетов, текста консоли и т.д.).
Объект, из которого можно считать данные, называется потоком ввода, а объект, в который можно записывать данные, - потоком вывода. Например, если надо считать содержание файла, то применяется поток ввода, а если надо записать в файл - то поток вывода.
В основе всех классов, управляющих потоками байтов, находятся два абстрактных класса: InputStream (представляющий потоки ввода) и
OutputStream (представляющий потоки вывода).
Но поскольку работать с байтами не очень удобно, то для работы с потоками символов были добавлены абстрактные классы Reader (для чтения потоков символов) и Writer (для записи потоков символов). Все остальные классы, работающие с потоками, являются наследниками этих абстрактных классов.
Какие интерфейсы реализует InputStream/ OutputStream/ Reader/
Writer?
InputStream реализует интерфейсы: Closeable и AutoCloseable
OutputStream реализует интерфейсы: Closeable, Flushable, AutoCloseable
Reader реализует интерфейсы: Closeable, AutoCloseable, Readable
Writer реализует интерфейсы: Closeable, Flushable, Appendable,
AutoCloseable
На каком паттерне основана иерархия потоков ввода/вывода?
Объекты классов Java, которые используются для ввода/вывода, для обеспечения необходимой функциональности наслаиваются друг на друга.
Такая модель взаимодействия объектов поддерживается в паттерне
«Декоратор». В этом паттерне при создании потока нужно использовать несколько объектов.
Назовите основные предки потоков ввода/вывода
Байтовые: java.io.InputStream, java.io.OutputStream;
Символьные: java.io.Reader, java.io.Writer;
В каких пакетах лежат классы-потоки?
Классы потоков ввода\вывода лежат в java.io / java.nio;
Для работы с архивами используются классы из пакета java.util

2)
Что делает метод read?
Метод read() используется для чтения символов. Метод читает следующий байт из входящего потока. Когда метод ничего не может считать (конец потока), возвращается -1. Он возвращает представление byte в 32-х битном виде.
Метод возвращает Int потому что нужно нужен такой тип, который может вместить 1 байт (0-255), плюс одно служебное значение -1, а диапазон byte в Java лежит от -128 до 127. Чтобы получить представление byte в int, в методе read() используется побитовое "И".
Что вернёт метод read() если считает (-1), а (-3)?
Вернёт 255. Если методу read() встречается байт равный -1, то он вернет значение, к которому применилось побитовое "И" с числом 255.
Если считает (-3), вернет 253
Что возвращает перегруженный read. Какое максимальное значение
вернет?
• Максимально, read может ввести 65534 байта, + индикатор ошибки (-1).
int read() - возвращает представление очередного доступного символа во входном потоке в виде целого числа.
int read(char[] buffer) - пытается прочесть максимум buffer.length символов из входного потока в массив buffer. Возвращает количество символов, в действительно сти прочитанных из потока.
int read(char[] buffer, int offset, int length) - пытается прочесть максимум length символов, расположив их в массиве buffer, начиная с элемента offset. Возвращает количество реально прочитанных символов
3)
Что такое System.in, что такое System.out?
Переменная System.out ссылается на стандартный поток вывода (по умолчанию консоль)
Переменная System.in ссылается на стандартный поток ввода (по умолчанию клавиатура)


4)
Что делает flush? Почему важно закрывать потоки?
Сбрасывает выходной поток и заставляет записывать буферные выходные байты.
Общий контракт flush состоит в том, что его вызов - это указание на то, что если какие-либо ранее записанные байты были буферизованы, такие байты должны быть немедленно записаны в предназначенный им пункт назначения.
Для обеспечения производительности данные сначала записываются в буфер. Когда буфер заполняется, данные записываются на вывод (Файл, консоль и т.д.). Когда буфер частично заполнен, но вы хотите отправить его на вывод (файл, консоль), тогда вам нужно вызвать метод flush() вручную, чтобы записать частично заполненный буфер для вывода (файл, консоль).
Почему важно закрывать потоки?
При закрытии потока освобождаются все выделенные для него ресурсы, например, файл. В случае, если поток окажется не закрыт, может происходить утечка памяти.
Можно ли использовать flush() для небуферизированного потока и что
будет?
МОЖНО среда хоста может выполнять свою собственную буферизацию, неизвестную Java. В этом случае запись можешь кэшироваться в буферах
ОС.
Гарантируется ли запись данных в файл при вызове flush()?
Если предполагаемое место назначения этого потока является абстракцией, предоставляемой базовой ОС, например файлом, то очистка потока гарантирует только то, что байты, ранее записанные в поток, передаются ОС для записи; это не гарантирует, что они действительно записаны на физическое устройство.
Выполнится ли flush если мы сделаем close у потока??
ДА, ВЫПОЛНИТСЯ Flush очищает буфер и скидывает содержимое в поток. В соответствии с документами java, вызывая close() на любом потоке java.io автоматически вызывает flush().
Какие потоки можно не закрывать (не вызывать метод close())?
Потоки с AutoCloseble интерфейсом. Например try-with-resourse.
Что делает метод available()?
Метод возвращает количество байт, которое еще осталось в потоке

5)
Расскажи про классы Reader и Writer?
Символьные потоки имеют два основных абстрактных класса Reader и Writer, управляющие потоками символов Unicode.
Абстрактный класс Reader предоставляет функционал для чтения
текстовой информации. Рассмотрим его основные методы:
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.
Возвращает число успешно пропущенных символов
BufferedReader
Буферизированный входной символьный поток
CharArrayReader
Входной поток, который читает из символьного массива
FileReader
Входной поток, читающий файл
FilterReader
Фильтрующий читатель
InputStreamReader
Входной поток, транслирующий байты в символы
LineNumberReader
Входной поток, подсчитывающий строки
PipedReader
Входной канал
PushbackReader
Входной поток, позволяющий возвращать символы обратно в поток
Reader


Абстрактный класс, описывающий символьный ввод
StringReader
Входной поток, читающий из строки
Класс Writer определяет функционал для всех символьных потоков
вывода. Его основные методы:
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
BufferedWriter
Буферизированный выходной символьный поток
CharArrayWriter
Выходной поток, который пишет в символьный массив
FileWriter
Выходной поток, пишущий в файл
FilterWriter
Фильтрующий писатель
OutputStreamWriter
Выходной поток, транслирующий байты в символы
PipedWriter
Выходной канал
PrintWriter
Выходной поток, включающий методы print() и println()

StringWriter
Выходной поток, пишущий в строку
Writer
Абстрактный класс, описывающий символьный вывод
Функционал, описанный классами Reader и Writer, наследуется непосредственно классами символьных потоков, в частности классами
FileReader и FileWriter соответственно, предназначенными для работы с текстовыми файлами.
6)
Как преобразовать считанные байты в символы? Какой класс для этого используется?
OutputStreamWriter — мост между классом OutputStream и классом
Writer. Символы, записанные в поток, преобразовываются в байты.
InputStreamReader — аналог для чтения. При помощи методов класса
Reader читаются байты из потока InputStream и далее преобразуются в символы. Преобразовать можем используя.io.InputStreamReader
(подкласс Reader), используем метод read(), и явное приведение к char
7)
Отличие Scanner’a от BufferedReader’a?
* Scanner имеет небольшой буфер (1KB буфер символов), а BufferedReader
(8KB байтовый буфер)
* BufferedReader работает синхронно, а Scanner — нет. BufferedReader
(работает с несколькими потоками)
* BufferedReader немного быстрее по сравнению со сканером, потому что сканер выполняет синтаксический анализ входных данных, а
BufferedReader просто читает последовательность символов.
* При использовании BufferReader нужно указывать IO Exception
Для чего нужен Scanner?
Scanner это класс в языке Java, который позволяет считывать данные из
разных источников. В том числе и с консоли.
Scanner используется для считывания введенных данных: String, byte, short, int, long, float, double
Что такое токен в Scanner?
Токен - это подстрока, не содержащая разделителей и ограниченная слева и справа разделителями. Стандартными разделителями являются: пробел, символ табуляции, перевода строки и возврата каретки.
Есть ли у Scanner буфер?


У сканнера есть буфер, его размер 1KB (Буфер символов)
8)
Отличие пакета io от nio?
Основное отличие: IO – потоко-ориентированный , а NIO - буферо- ориентированным
(IO) Потоко-ориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно.
Блокирующий ввод-вывод
Потоки ввода/вывода (streams) в Java IO являются блокирующими.
Это значит, что когда в потоке выполнения (tread) вызывается read() или write() метод любого класса из пакета java.io.*, происходит блокировка до тех пор, пока данные не будут считаны или записаны.
Поток выполнения в данный момент не может делать ничего другого
Потоко-ориентированный ввод-вывод
Потоко-ориентированный ввод/вывод подразумевает чтение/запись из потока в поток одного или нескольких байт в единицу времени поочередно. Данная информация нигде не кэшируются. Таким образом, невозможно произвольно двигаться по потоку данных вперед или назад. Если вы хотите произвести подобные манипуляции, вам придется сначала кэшировать данные в буфере.
(NIO) – Буферо-ориентированный, данные считываются в буфер для последующей обработки.
Неблокирующий ввод-вывод
Неблокирующий режим NIO позволяет запрашивать считанные данные из канала (channel) и получать только то, что доступно на данный момент, или вообще ничего, если доступных данных пока нет. Вместо того, чтобы оставаться заблокированным пока данные не станут доступными для считывания , поток выполнения может заняться чем-то другим.
9)
Расскажи про класс File? Как создать новый файл на жестком диске?
В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу.
А также осуществлять навигацию по иерархиям подкаталогов.

Класс java.io.File может представлять имя определённого файла, а также имена группы файлов, находящихся в каталоге. Если класс представляет каталог, то его метод list() возвращает массив строк с именами всех файлов.
Для создания объектов класса File можно использовать один из следующих конструкторов.

File(File dir, String name) - указывается объекта класса File (каталог) и имя файла

File(String path) - указывается путь к файлу без указания имени файла

File(String dirPath, Sring name) - указывается путь к файлу и имя файла

File(URI uri) - указывается объекта URI, описывающий файл
Класс File может использоваться для создания каталога или дерева каталогов.
Также можно узнать свойства файлов (размер, дату последнего изменения, режим чтения/записи), определить к какому типу (файл или каталог) относится объект File, удалить файл. У класса очень много методов, перечислим некоторые.

getAbsolutePath() - абсолютный путь файла, начиная с корня системы.
В Android корневым элементом является символ слеша (/)

canRead() - доступно для чтения

canWrite() - доступно для записи

exists() - файл существует или нет

getName() - возвращает имя файла

getParent() - возвращает имя родительского каталога

getPath() - путь

lastModified() - дата последнего изменения

isFile() - объект является файлом, а не каталогом

isDirectory - объект является каталогом

isAbsolute() - возвращает true, если файл имеет абсолютный путь

renameTo(File newPath) - переименовывает файл. В параметре указывается имя нового имени файла. Если переименование прошло неудачно, то возвращается false

delete() - удаляет файл. Также можно удалить пустой каталог
Вызвать метод createNewFile() и передать имя файла (все вместе - инициализация объекта File)
Создать файл в Java с помощью объекта File можно тремя способами:
1. Передав в объект абсолютный путь


2. Указать только имя файла
3. Указать относительный путь (корневая директория проекта)
Какой класс предназначен для работы с элементами файловой системы
(ЭФС)?
Класс File работает непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, дата создания, путь к каталогу. А также осуществлять навигацию по подкаталам.
10)
В чём отличие File от Path?
* Многие методы класса File не сообщают нам никаких подробностей о возникшей проблеме или даже вообще не выдают исключений, в отличии от методов Path.
* Поддержка метаданных. Класс файла в java.io пакет имеет плохую поддержку метаданных, что приводит к проблемам на разных платформах с операциями ввода-вывода. Метаданные могут также включать разрешения, владельца файла и атрибуты безопасности. Из-за этого класс File вообще не поддерживает символические ссылки, а метод rename() не работает согласованно на разных платформах.
* Производительность Вместо File в пакете NIO появились такие классы, как Paths, Path, Files.
Методы класса File
mkdir() создает каталог
createNewFile() создает новый файл, true
delete() удаляет файл, true
renameTo() переименовывает
exists() проверяет есть ли каталог или файл, true
isDirectory() если есть каталог, true
isFile() если находится файл, true
getAbsolutePath() возвращает путь, String
getName() имя, String
getParent() имя род класса, String
list() возвращает массив файлов и каталогов
11)
В чем разница между абсолютным и относительным путем?
Абсолютный (полный) путь — это путь, который указывает на одно и то же место в файловой системе, вне зависимости от текущей рабочей директории или других обстоятельств. Полный путь всегда начинается с корневого каталога.

Относительный путь представляет собой путь по отношению к текущему рабочему каталогу пользователя или активного приложения.
Канонический путь?
Это тот путь, который будет максимально простым и строгим "каноничным". То есть, без всех этих странных конструкций. canonical
path: C:\abc\file.txt absolute path: C:\abc\..\abc\file.txt
Какой символ является разделителем при указании пути к ЭФС?
Для различных систем символ разделителя различается.
Вытащить его можно используя file.separator, а так же в статическом поле
File.separator.
Вроде как для всех систем можно использовать « \ ».
12)
Что такое клонирование? Как реализовано клонирование в Java?
Иногда необходимо на основе существующего объекта создать второй такой же - то есть создать его клон. Это процесс в Java называется клонированием.
Клонировать объект в Java можно тремя способами:
1. Использовать конструктор копирования;
2. Переопределить метод clone() и реализовать интерфейс Cloneable;
3. Использовать для клонирования механизм сериализации;
Чем отличается копирование от клонирования?
Clone - создаёт что-то новое на основе чего-то существующего.
Копирование-копирование с чего-то существующего на что-то другое
Можно ли клонировать String, массив String?
(?)
Строку нет, массив можно
13)
Как удалить директорию с файлами?
Методом delete. Директория будет удалена только в случае если в ней нет файлов, либо вложенных директорий. Чтобы удалить директорию с файлами, сначала необходимо удалить сами файлы в папке, а затем и саму папку (обычно используется рекурсия).
14)
В чём разница между поверхностным и глубоким клонированием? Как реализовать глубокое клонирование?
Поверхностное клонирование применяется только с примитивными полями (метод clone ()).