INPUT/OUTPUT
|
ВОПРОС
| ОТВЕТ
|
Чем отличаются байтовый и символьный потоки?
| Байтовый поток передает и считывает байты (byte, 1 байт), символьный - символы (char, 2 байта)
|
Что такое байтовый поток? Как он реализован внутри?
| 1) Байтовый поток в Java - это объект InputStream/OutputStream. 2) В потоке можно прочитать или записать один или несколько байтов. 3) Внутри есть абстрактный метод read() / write(int b), для чтения/записи одного байта. Реализация этого метода и определяет фактическую реализацию потока. 4) Также есть метод read(byte[] buf) / write(byte[] buf) для записи сразу массива байтов.
|
Что такое символьный поток? Как он реализован внутри?
| 1) Символьный поток в Java - это объект Reader/Writer. 2) В потоке можно прочитать или записать один или несколько символов (char, 2 байта). 3) Внутри есть один абстрактный метод: read(char[] cbuf, int off, int len) или write(char cbuf[], int off, int len) Реализация этого метода и определяет фактическую реализацию работы объекта. 4) Также дополнительно есть метод read() / write(int c) для чтения/записи одного символа или write(String) для записи строки (набора символов).
|
В чем разница между классами InputStream/OutputStream и Reader/Writer? Как они соотносятся между собой?
| 1) InputStream/OutputStream - это потоки байтов (byte). Reader/Writer - потоки символов (char) 2) Reader/Writer используют I/OStream для чтения/записи байтов, а затем расшифровывают байты как символы.
|
Что такое поток ввода-вывода?
| 1) Поток ввода/вывода - это абстракция, которая используется для чтения или записи информации с некоторого физического ресурса (файл, сокет, ввод пользователя и т.д.) 2) Поток в Java - это объект, из которого мы можем прочитать (поток ввода) или в который мы можем записать (поток вывода) некоторые данные.
|
Назовите два базовых класса для всех потоков ввода-вывода в Java.
| 1) Базовые классы потоков IO в Java - абстрактные классы java.io.InputStream и java.io.OutputStream. 2) Классы представляют поток байтов, записываемый в какой-то внешний ресурс. 3) В классах есть всего один абстрактный метод - запись или чтение одного байта: wrtite(int) или read(int). Остальные методы работают на его основе.
|
Что такое Java IO?
| IO = Input/Output 1) Библиотека классов, находящаяся в пакете java.io. 2) Назначение - предоставление API для работы с потоками ввода-вывода.
|
Что такое Java NIO? Когда это появилось? Зачем это нужно?
| NIO = Non-Blocking (New) Input/Output 1) Библиотека классов, находящаяся в пакете java.nio. 2) Появилась в Java 1.4. 3) Назначение - реализации неблокирующих, буфер-ориентированных операций ввода-вывода.
|
Какие проблемы класса File из java.io заставили придумывать java.nio?
| Проблемы класса java.io.File: 1) Нет метода copy() для копирования файла/каталога. 2) Методы в основном возвращают true/false, а не бросают исключение. Сложно искать ошибки. 3) Нельзя создать символическую ссылку. 4) Неэффективно обрабатывает файлы/каталоги, проблема с масштабированием. 5) Предоставляет доступ к очень ограниченному набору атрибутов файлов.
|
Что такое символьная ссылка?
| 1) Символьная ссылка (Symbolic link) - это специальный файл, являющийся ссылкой на другой файл. 2) Симлинк содержит только строку, в которой записан путь к нужному файлу в файловой системе. 3) При обращении к симлинку должен открываться файл, на который симлинк ссылается. 4) Как правило, симлинки прозрачны для приложений: симлинк можно читать и писать, при этом чтение/запись по факту идут с тем файлом, на который ссылается симлинк.
|
Какие ключевые особенности появились в NIO, появившемся в java 1.4?
| 1) Неблокирующее чтение. Каналы. Буферы. 2) Селекторы. 3) Кодеры/декодеры для стандартных кодировок, преобразующие текст в поток байтов и наоборот.
|
Какие ключевые особенности появились в Java NIO при выходе java 1.7?
| Также пакет называют Java NIO.2 1) Новый пакет java.nio.file. Path, Paths, Files. 2) Лучшая поддержка симлинков. 3) Доступ ко всем атрибутам файлов 4) Доступ к работе с файловой системой
|
Назовите ключевые отличия между Java IO и Java NIO.
| 1) IO – потокоориентированный, NIO – буфероориентированный;
2) IO – синхронный блокирующий ввод/вывод,NIO – неблокирующий ввод/вывод;
3) в NIO есть селекторы, в IO – их нет
|
(Java NIO) Что такое каналы?
| 1) Каналы (channel) - открытое соединение с источником или адресатом ввода/вывода. 2) Через каналы осуществляется ввод вывод данных. 3) Вывод данных: вы --> буфер --> канал. 4) Ввод данных: канал --> буфер --> вы.
|
Какие преимущества имеет неблокирующий режим ввода/вывода в Java NIO?
| 1) Поток запрашивает данные из канала, считывает то, что доступно. Он не остается заблокированным и не ждет вхолостую, пока мы прочитаем все данные от ресурса. 2) То же - поток вывода. Поток может попросить запись данных в канал, но не ждет, пока они все полностью запишутся. 3) Таким образом, один поток ввода/вывода может использоваться многократно на разных задачах.
|
(Java NIO) Что такое селекторы? Зачем они нужны?
| 1) Селектор (java.nio.channels.Selector) - объект, который содержит в себе несколько каналов и позволяет переключаться между ними. 2) Селектор позволяет одному потоку ввода/вывода обслуживать сразу несколько каналов, не простаивая зря. 3) Аналогия: три ж/д пути на вокзале и три постоянно ждущих работника или один работник на три пути, который перемещается к пришедшему поезду.
|
В чем разница при буферном чтении данных Java NIO и потоковом чтении Java IO?
| В случае с IO метод read() поочередно читает данные, метод readLine() – блокирующий, гарантирующий, что строка будет прочитана;
В NIO данные читаются в буфер – чтение НЕ блокирующее, буфер может быть заполнен не до конца. В связи с этим необходимо проверять, заполнен буфер или нет.
|
В каком случае при чтении/записи данных лучше использовать Java IO, а когда - Java NIO?
| 1) Java IO - если не очень много источников, через которые передается большое число данных. 2) Java NIO - если очень много источников, через каждый из которых передается малое количество данных.
|
Какие методы класса java.nio.file.Path вы знаете?
| 1) getFileName() 2) getParent() 3) getRoot() 4) getName(i) 5) getNameCount() 6) subPath() 7) normalize() 8) toAbsolutePath() 9) toRealPath() 10) resolve() 11) relativize() 12) iterator() 13) toUri() 14) toFile()
|
Что делает метод java.nio.file.Path.toRealPath() ?
| Метод toRealPath: 1) Заменяет все symlink (если есть) на реальный путь к файлам. 2) Делает toAbsolutePath() 3) Делает normalize()
|
1) Что делает метод java.nio.file.relativize()? 2) Дано: Path p1= Paths.get("/home"); Path p2= Paths.get("/home/sally/bar"); Path p3 = Paths.get("/lib"); Что вернут методы: 2.1) p1.relativize(p2) ? 2.2) p2.relativize(p1) ? 2.3) p1.relativize(p3) ?
| 1) Метод p1.relativize(p2) возвращает Path - путь от p1 к p2. 2.1) p1.relativize(p2) ==> Path("sally/bar") 2.2) p2.relativize(p1) ==> Path("../..") 2.3) p1.relativize(p3) ==> Path("../lib")
|
Дано: Path path = Paths.get("C:\\home\\joe\\foo"). Что вернут методы: path.resolve(Paths.get("muu"))?path.resolve(Paths.get("C:\\muu"))?
| 1) path.resolve(Paths.get("muu")) ==> объект Path("C:\home\joe\foo\muu") 2) path.resolve(Paths.get("C:\\muu")) ==> объект Path("C:\\muu")
|
Дано: Path path = Paths.get("C:\\home\\joe\\foo"). Что вернет метод path.toUri() ?
| Метод path.toUri() вернет объект java.net.URI со ссылкой: file:///C:/home/joe/foo
|
Дано: Path path = Paths.get("C:\\home\\joe\\foo"). Что вернут методы: 1) path.getName(0) ? 2) path.getName(2) ? 3) path.getName(5) ? 4) path.getName(-2) ?
| 1) path.getName(0) ==> "home" 2) path.getName(2) ==> "foo" 3) path.getName(5) ==> IllegalArgumentException 3) path.getName(-2) ==> IllegalArgumentException
|
Дано: Path path = Paths.get("C:\\home\\joe\\foo"). Что вернут методы: 1) path.subpath(0,2) ? 2) path.subpath(-1,2) ? 3) path.subpath(1, 5) ? 4) path.subpath(2,1) ? 5) path.subpath(1,1) ?
| 1) path.subpath(0,2) ==> "home\joe" 2) path.subpath(-1,2) ==> IllegalArgumentException 3) path.subpath(1, 5) ==> IllegalArgumentException 4) path.subpath(2,1) ==> IllegalArgumentException 5) path.subpath(1,1) ==> IllegalArgumentException
|
Дано: Path path = Paths.get("C:\\home\\joe\\foo"). Что вернет метод path.iterator()
| Метод path.iterator() вернет итератор по элементам: типа Path со значениями: 1) Path("home") 2) Path("joe") 3) Path("foo")
|
Что делает метод java.nio.files.Path.normalize()
| Метод path.normalize() удаляет лишние "." и ".." из пути к файлу/папке.
|
Какие методы класса java.nio.file.Files вы знаете?
| 1) isSameFile() 2) isDirectory() 3) exists() 4) isSymbolicLink() 5) isReadable()/isWriteable()/isExecutable()/isHidden 6) get/setAttribute(path, attrName), например Files.getAttribute(p, "creationTime"); 7) copy()/move() 8) delete()/deleteIfExists() 9) walkFileTree(Path root, FileVisitor visitor)
|
Напишем в UNIX-системе: Path p = Paths.get("/"); String name = p.getFileName(); boolean exists = Files.exists(p); Чему равны name и exists?
| String name == null, exists = true
|
Мы вызываем Files.delete(path). Path указывает на файл, но файл не существует. Результат?
| Исключение: java.nio.file.NoSuchFileException
|
Мы вызываем Files.delete(path). Path указывает на директорию, но директория не пуста. Результат?
| Исключение: java.nio.file.DirectoryNotEmptyException
|
Чем отличаются методы delete() и deleteIfExists() класса java.nio.file.Files?
| В случае, если файл, на который указывает Path, не существует, метод delete() выкидывает NoSuchFileException, а метод deleteIfExists() просто возвращает false.
|
Какие методы имеет интерфейс java.nio.file.FileVisitor()?
| Все методы вовразают FileVisitResult. 1) preVisitDirectory(T dir, BasicFileAttributes attrs) - до того, как посещать файлы в этой директории. 2) visitFile(T file, BasicFileAttributes attrs) - при доступе к файлу. 3) postVisitDirectory(T dir, IOException e) - после того, как посетил все файлы в этой директории. 4) visitFileFailed(T file, IOException e) - если к файлу нет доступа.
|
Какие объекты FileVisitResult, возвращаемые методами интерфейса FileVisitor, контролируют процесс обхода дерева файлов?
| 1) CONTINUE: продолжать обход. 2) TERMINATE: немедленно прекратить обход. 3) SKIP_SUBTREE: пропустить все подкаталоги. 4) SKIP_SIBLINGS: прекратить обход всех файлов/каталогов этого уровня: --- Если из visitFile() - то файлов в этом каталоге. --- Если из preVisitDirectory() - пропустить каталог, его содержимое, предотвратить вызов postVisitDirectory(), плюс пропустить каталоги, находящиеся в той же папке, что и данный каталог --- Если из postVisitDirectory() - то каталоги, находящиеся в той же папке, что и только что обойденный каталог. Все объекты-ответы получаются как статические поля класса. Например: return FileVisitResult.CONTINUE.
|
Зачем нужен интерфейс java.nio.PathMatcher? Как им воспользоваться?
| 1) Интерфейс PathMatcher позволяет искать файлы по регулярному выражению (regex). 2) Получить объект PathMatcher: matcher = FileSystem.getPathMatcher(String pattern); 3) Метод matcher.matches(Path path) возвращает true/false - проходит имя файла (или путь,если указан с "/" или "C:\\") по regexp или нет. 4) Можно, например, сделать FileVisitor, проверять имя файла и выписывать подходящие.
|
(Java NIO) Как можно отслеживать, что в каталоге добавился/удалился/изменился файл?
| 1) Интерфейс java.nio.file.WatchService. 2) Получить объект: WatchService ws = fileSystem.newWatchService(); 3) Зарегистрировать в объекте Path: path.register(ws, matchers...) - список событий. 4) Получать события: WatchKey key = ws.take() - ждет, пока произойдет событие.
|
(Java NIO) Какие типы матчеров для объекта WatchService вы помните? К какому классу они относятся?
| Все события - поля в классе java.nio.file.StandardWatchEventKinds. Относятся к классу java.nio.file.WatchEvent.Kind. 1) ENTRY_CREATE - создан новый файл. 2) ENTRY_DELETE - удален файл. 3) ENTRY_MODIFY - файл изменен.
|
(Java NIO) Как получить объект FileSystem для текущей системы
| FileSystem fs = FileSystems.getDefault()
|
(I/O) Что делает метод flush() ? С какого класса он начинается?
| 1) Метод flush() - переводится как "в один уровень" или "смыть".2 2) Метод записывает все данные, находящиеся в буфере, на носитель. 3) Носитель - это файл на диске, сетевое соединение, объект в памяти и т.д., который представлен как поток вывода. 4) Метод flush() указан в классе OutputStream, но там он пуст - поскольку у простого OutputStream буфера нет, и каждый байт сразу записывается на диск.
|
Какие символы объект java.util.Scanner принимает как разделитель токенов по-умолчанию?
| 1) Пробелы, отступы (tab) и разделители строк. 2) Полный лист - в методе Character.isWhitespace()
|
Какие методы класса Scanner вы помните?
| 1) (has)next() 2) (has)nextByte (Short, Int, Long, Double, 3) (has)nextBigInteger (BigDecimal) 4) (has)nextLine() 5) useDelimiter() (Radix, Locale) 6) reset() - default delimiter, radix, locale 7) close() - вызывает также close() у обернутого потока.
|
Как задать свой символ-разделитель для объекта класса Scanner?
| Другой разделитель задается методом scanner.useDelimiter(String regexp); Например: scanner.useDelimiter(",\\s*"); означает, что разделитель - "запятая, после которой может быть один пробел".
|
Что такое Scanner?
| Класс java.util.Scanner представляет объект, который читает InputStream и разбирает его на набор данных определенного типа.
|
Как работает Scanner внутри?
| 1) Сканер преобразует входящий поток в поток текстовых символов. 2) Этот поток он разбивает на кусочки - "токены". 3) Токен - это текст, перед и после которого стоит заданный символ-разделитель. 4) В методе next() сканер просто выдает следующий токен. 5) В методах же вроде nextInt() сканер находит с помощью regexp токен, который можно преобразовать в нужный тип (int) и выдает его уже преобразованным в этот тип.
|
(Java I/O) Что такое буферизированный поток?
| 1) Буферизированный поток - это поток ввода-вывода, который использует буфер. 2) Буфер - это объект в памяти, содержащий в себе прочитанные или записываемые данные. 3) При вводе/выводе приложение общается с буфером, а буфер - непосредственно с API физического носителя (файловой системы и т.д.).
|
(Java I/O) Какие преимущества имеет буферизированный поток ввода/вывода перед обычным?
| 1) Небуферизированный при получении/записи каждого байта "дергает" физический объект - например, идет обращение к диску. Это медленно. Буферизированный - берет или записывает данные одним большим куском. 2) Буферизированный поток ввода позволяет идти по данным не только вперед, но и возвращаться назад (методы mark() и reset(), реализуемые классом BufferedInputStream).
|
Какой по умолчанию размер буфера в BufferedInput/OutputStream, BufferedReader/Writer ? Как изменить размер буфера?
| 1) Вообще, величина буфера по-умолчанию зависит от реализации JVM. 2) Вроде как стандартный размер буфера по умолчанию - 8192 байта (8 килобайт). 3) Изменить - при создании объекта в конструкторе. Например: new BufferedReader(Reader in, int bufSize).
|
(Java I/O) Какие классы позволяют осуществить форматированный вывод?
| 1) Форматированный вывод базово осуществляют классы java.io.PrintWriter и java.io.PrintStream. 2) В них есть метод format() для вывода значений в заданном формате. 3) Также в классе String есть метод String.format(), выдающий строку, форматированную аналогично тому, как в методе PrintStream.format().
|
Чем отличаются классы java.io.PrintWriter и java.io.PrintStream?
| 1) PrintWriter - символьный поток данных. 2) PrintStream - байтовый поток данных.
Однако, оба этих класса имеют возможность форматированного вывода строки (методы print(), println() и format()).
|
Расшифруйте элементы выражения: System.out.format( "%1$+020.10f %n", Math.PI);
| По порядку: '%': ключ, обозначающий, что за ним идет описание форматирования '1$': взять первый аргумент: format("format", arg1, arg2, arg3...). '+' - обязательно указать знак выражения ("+" или "-") '0' - флаг, означающий, что нужно добавить нули перед выражением, если оно будет слишком коротким. '20' - минимальная ширина вывода (сколько символов он должен занять). По умолчанию печатается слева, недостающие символы заполняются пробелами. '10' - количество нулей после запятой для десятичной дроби. f - вывод числа с плавающей точкой как десятичной дроби %n - знак конца строки.
|
Имеем: PrintStream.format("%20d", 10) С какой стороны от "10" будут заполняющие пробелы? Можно ли это изменить?
| 1) Заполняющие пробелы будут слева. Выравнивание по правому краю. 2) Сделать по левому краю - знак '-'. Выражение "%-20d" выравнивает по левому краю, и заполняющие пробелы будут справа.
|
(Java I/O) Что такое поток данных (DataStream)?
| 1) Поток данных - это поток, который дополнительно переводит байты в один из примитивных типов данных (int, double, boolean, char...). 2) Все потоки данных (data stream) реализуют интерфейс DataInput или DataOutput. 3) Самые широко используемые классы - это DataInputStream и DataOutputStream.
|
Какие методы из интерфейсов DataInput/DataOutput вы помните?
| 1) readBoolean / writeBoolean (Byte, Short, Int, Long, Float, Double, Char). 2) readLine / writeChars - конвертирует каждый ОДИН БАЙТ в символ char. Т.е. будет диапазон (char) [0-255]. 3) readUTF / writeUTF - читают/пишут строку в "слегка измененном формате UTF-8". В этом формате большинство восточноевропейских букв находятся в пределе одного байта. Но этот метод расшифровывает символы, занимающие и по ДВА И БОЛЕЕ БАЙТА.
|
В интерфейсе java.io.DataInput есть методы readLine() и readUTF(). Чем они отличаются?
| 1) Метод readLine() читает КАЖДЫЙ байт строки и переводит его в символ. Например, читая UTF-8 строку /🔒/ методом readLine(), мы получим /Yð``/ . 2) Метод readUTF читает строку в "модифицированной" кодировке UTF-8, при этом понимая и двухбайтовые символы. Записав cтроку /🔒/ с помощью DataInput.writeUTF() и читая затем с помощью DataInput.readUTF(), мы снова получим /🔒/ .
|
(Java I/O). Что такое поток объектов (ObjectStream)?
| 1) Поток объектов (ObjectStream) расширяет поток данных, добавляя методы для чтения/записи объектов java как потока байтов. 2) Все потоки объектов реализуют интерфейс ObjectInput или ObjectOutput. Эти интерфейсы extend DataInput и DataOutput. 3) Самые широко используемые классы - это ObjectInputStream и ObjectOutputStream.
|
Какие методы из интерфейсов ObjectInput/ObjectOutput вы помните?
| 1) Все методы из DataInput/DataOutput, поскольку эти интерфейсы их наследуют. 2) readObject/writeObject.
|
Как осуществляется ввод и вывод из командной строки?
| Ввод и вывод из командной строки осуществляются с помощью трех байтовых потоков: 1) System.in: байтовый InputStream. 2) System.out: байтовый PrintStream. 3) System.err: байтовый PrintStream.
|
Как прочитать данные и выдать данные пользователю через консоль, НЕ используя класс java.io.Console и java.util.Scanner ?
| 1) System.in нужно оборачивать в Reader, поскольку это байтовый поток. 2) Потоки System.out и System.err тоже байтовые, но их оборачивать не требуется, поскольку они PrintStream и уже могут print/println/format.
|
Что такое класс Console? Как получить объект Console?
| 1) Класс java.io.Console - специальный класс для простой работы с консолью. 2) Класс Console представлен одним объектом, который можно получить методом System.console()
|
Какие методы класса Console вы знаете?
| 1) String readLine(String fmt, Object... args) 2) char[] readPassword(String fmt, Object... args) - reads with echoing disabled 3) Reader() / PrintWriter() - получить объект, который читает/пишет в системную консоль. 4) printf() / format() 5) flush()
|
В чем разница между методами java.io.Console printf() и format()
| Между этими методами нет никакой разницы - они ведут себя абсолютно одинаково.
|
(Java I/O) Что такое Path? Как он реализуется на разных операционных системах?
| 1) Path - это путь к файлу в иерархии файловой системы. 2) В зависимости от системы уровни иерархии разделяются знаком '/' (slash) или '\' (backslash). 3) В Windows - файловая система с несколькими корневыми элементами (диски C:, D:), в Solaris - с одним корнем ('/', root).
|
Чем отличается абсолютный путь к файлу от относительного?
| 1) Абсолютный путь начинается от корня, и он однозначно указывает путь к файлу в файловой системе. 2) Относительный путь начинается от какой-то папки (обычно от той, где мы сейчас находимся). Без дополнительной информации о том, где находится эта папка, мы не можем однозначно сказать, где файл.
|
Как создать объект java.nio.file.Path?
| 1) FileSystems.getDefault().getPath(String s) 2) Path a = Path.of(String s) 3) Path b = Paths.get(String s)
|
(Java NIO) Как проверить, что файл или папка существуют на диске с помощью класса Files?
| Files.exists(Path path, LinkOption...) Files.notExists(Path path, LinkOption...)
|
(Java NIO) Зачем сделали методы Files.exists() и Files.notExists()? Не проще ли использовать !Files.exists() ?
| Дело в том, что !Files.exists() != Files.notExists(). Если невозможно понять, доступен ли файл или нет (нет доступа), то методы вернут: Files.exists(): false Files.notExists(): false !(Files.exists()): true
|
(Java NIO) Как проверить права доступа к файлу с помощью класса Files?
| Files.isReadable(Path path) Files.isWriteable(Path path) Files.isExecutable(Path path)
|
(Java NIO) Что проверяет метод Files.isRegularFile() ?
| Метод проверяет, что файл в данной path - обычный файл с данными, а не устройство, зашифрованный том диска или какой-то порт. Пример "необычного файла": /dev/null
|
(Java NIO) Когда может пригодиться метод Files.isSameFile()
| Если в системе есть символьные ссылки, то два пути с разным "строковым" представлением на самом деле указывают на один и тот же файл. Метод Files.isSameFile() расшифровывает симлинки и сверяет получившиеся пути.
|
(Java NIO) Как удалить файл с помощью класса Files?
| 1) Files.delete(Path path) - удаляет файл или папку. Может бросить NoSuchFileException или DirectoryNotEmptyException. 2) Files.deleteIfExists() - удаляет файл или папку. В случае проблем просто возвращает false.
|
(Java NIO) Пусть "/home/symwork" - симлинк, ссылающийся на "/home/john/work". Что будет при вызове Files.delete(Path.of("/home/symwork")) ?
| Files.delete(), как и deleteIfExists() удалит симлинк "/home/symwork", а файл или папка, на которую он ссылался, останется без изменений.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|