9. Ввод/Вывод (I/O) Flashcards
Какие способы работы с файлами вы знаете?
Пакет io: класс File File file = new В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу. А также осуществлять навигацию по иерархиям подкаталогов. . Пакет nio: классы Path и Files
Чем отличается относительный от абсолютного пути к файлу?
Абсолютный путь - это путь, который указывает на одно и то же место в файловой системе,
вне зависимости от каталога из под которого была запущена программа (java-процесс).
Абсолютный путь всегда начинается с корневого каталога.
Например:
C:\filewriter\text.txt
Относительный путь представляет собой путь по отношению к каталогу из-под которого
запущена программа (java-процесс).
Какие методы знаете у класса File?
File file = new File(“/home/maksaimer/file”);
Не требуют доступ к ФС:
file.isAbsolute() - проверяет является ли путь абсолютным или нет
file.getAbsolutePath() - возвращает абсолютный путь
file.getPath() - возвращает строку, соответствующую пути, переданную в
конструктор
file.getName() - возвращает имя файла
file.getParent() - возвращает путь до файла
file.getCanonicalFile()
file.getCanonicalPath() - возвращают абсолютный и уникальный путь для классов File/Path
Требуют доступ к ФС:
file.exists() - существует файл или каталог
file.canRead()/canWrite()/canExecute()
file.length - длинна в байтах файла
file.isFile()/isDirectory()/isHidden
file.createNewFile() - если нет файла - создаёт
file.mkdir()/mkdirs - создаёт каталог/каталоги
file.delete - удаляет файл
Что такое потоки в Java? Назовите основные классы (без потомков).
(Stream). Поток - это абстрактное значение источника или приёмника данных, которые способны обрабатывать информацию.
Классы потоков -
(абстрактные)
InputStream:
Базовый класс InputStream представляет классы, которые получают данные из различных источников:
массив байтов
строка (String)
файл
канал (pipe): данные помещаются с одного конца и извлекаются с другого
последовательность различных потоков, которые можно объединить в одном потоке
другие источники (например, подключение к интернету)
(http://developer.alexanderklimov.ru/android/java/inputstream.php)
OutputStream:
Класс OutputStream - это абстрактный класс, определяющий потоковый байтовый вывод.
(http://developer.alexanderklimov.ru/android/java/io.php)
Разделяют два вида потоков ввода/вывода: байтовые и символьные.
Назовите основные методы потоков и коротко расскажите что они делают?
InputStream:
int available() - возвращает количество байтов ввода, доступные в данный момент для чтения
close() - закрывает источник ввода. Следующие попытки чтения передадут исключение IOException
void mark(int readlimit) - помещает метку в текущую точку входного потока, которая остаётся корректной до тех пор, пока не будет прочитано readlimint байт
boolean markSupported() - возвращает true, если методы mark() и reset() поддерживаются потоком
int read() - возвращает целочисленное представление следующего доступного байта в потоке. При достижении конца файла возвращается значение -1
int read(byte[] buffer) - пытается читать байты в буфер, возвращая количество прочитанных байтов. По достижении конца файла возвращает значение -1
int read(byte[] buffer, int byteOffset, int byteCount) - пытается читать до byteCount байт в buffer, начиная с смещения byteOffset. По достижении конца файла возвращает -1
reset() - сбрасывает входной указатель в ранее установленную метку
long skip(long byteCount) - пропускает byteCount байт ввода, возвращая количество проигнорированных байтов.
———————————————————————————–
OutputStream:
void write(int b) - записать один байт в поток (старшие 3 байта будут проигнорированы)
void write(byte[] b) - записать в поток байты из массива
void write(byte[] b, int off, int len) - записать в поток байты из массива, с указанием начала
массива и количества байт
void flush() - если у потока есть буфер, куда сохраняются данные прежде, чем попасть в
место назначения, то вызов этого метода опустошает этот буфер и отправляет данные в
место назначения.
void close() - закрывает поток, подразумевает вызов flush()
Какие реализации потоков вы знаете и чем они отличаются?
InputStream:
InputStream - Абстрактный класс, описывающий поток ввода
BufferedInputStream
Буферизированный входной поток
ByteArrayInputStream - Позволяет использовать буфер в памяти (массив байтов) в качестве источника данных для входного потока.
DataInputStream - Входной поток, включающий методы для чтения стандартных типов данных Java
FileInputStream - Для чтения информации из файла
FilterInputStream - Абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства.
ObjectInputStream - Входной поток для объектов
StringBufferInputStream -Превращает строку (String) во входной поток данных InputStream
PipedInputStream
Реализует понятие входного канала.
PushbackInputStream - Входной поток, поддерживающий однобайтовый возврат во входной поток
SequenceInputStream - Сливает два или более потока InputStream в единый поток.
———————————————————————————–
OutputStream:
BufferedOutputStream - Буферизированный выходной поток
ByteArrayOutputStream - Создает буфер в памяти. Все данные, посылаемые в этот поток, размещаются в созданном буфере
DataOutputStream - Выходной поток, включающий методы для записи стандартных типов данных Java
FileOutputStream - Отправка данных в файл на диске. Реализация класса OutputStream
ObjectOutputStream - Выходной поток для объектов
PipedOutputStream - Реализует понятие выходного канала.
FilterOutputStream - Абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства.
———————————————————————————–
Классы-надстройки наделяют существующий поток дополнительными свойствами. Примеры классов: BufferedOutputStream, BufferedInputStream, BufferedWriter — буферизируют поток и повышают производительность.
Коротко расскажите как бы вы копировали файл?
Класс Files: private static void copyFileUsingJava7Files(File source, File dest) throws IOException { Files.copy(source.toPath(), dest.toPath()); } Потоки: private static void copyFileUsingStream(File source, File dest) throws IOException { InputStream is = null; OutputStream os = null; try { is = new FileInputStream(source); os = new FileOutputStream(dest); byte[] buffer = new byte[1024]; int length; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } } finally { is.close(); os.close(); } }
Что такое потоки символов и назовите основные классы?
Reader(FileReader) и Writer(FileWriter)
java.io.Reader, java.io.Writer
Символьные потоки имеют два основных абстрактных класса Reader и Writer, управляющие потоками символов Unicode. Класс Reader — абстрактный класс, определяющий символьный потоковый ввод. Класс Writer — абстрактный класс, определяющий символьный потоковый вывод. В случае ошибок все методы класса передают исключение IOException.
Назовите основные методы потоков символов и коротко расскажите что они делают?
Методы аналогичны InputStream.
int read() - прочитать из потока один символ (заполняется младшие два байта int,
остальные байты нули), если в потоке данных больше нет, то вернётся -1.
int read(char[] cbuf) - прочитать из потока в массив символов.
int read(char[] cbuf, int off, int len) - прочитать из потока в массив символов, с
указанием начала массива и количества прочитанных символов.
Эти два метода возвращают фактическое количество байт.
void close() - закрыть поток.
.
Методы аналогичны OutputStream.
void write(int c) - записать символ в поток (старшие два байта будут проигнорированы)
void write(String str) - записать строку в поток
void write(char[] cbuf) - записать массив символов в поток
void write(char[] cbuf, int off, int len) - записать массив символов в поток, начиная с
некоторого индекса,
void flush() - принудительно отправить данные в поток, опустошив буффер.
void close() - подразумевает flush().
Какие реализации символьных потоков вы знаете и чем они отличаются?
Reader - BufferedReader, CharArrayReader, StringReader, InputStreamReader - FileReader
.
Writer - BufferedWriter, CharArrayWriter, StringWriter, OutputStreamWriter - FileWriter
Что такое сериализация и как она работает?
Сериализация - процесс трансформации состояния java-объекта в последовательность байт, десериализация - обратный процесс. Статические
поля не сериализуются.
Если класс содержит поля ссылочных типов, то при сериализации каждый тип
должен быть помеченным Serializable.
Конструктор по умолчанию не обязателен, как в Externalizable.
Чтобы обладать способностью к сериализации, класс должен реализовывать интерфейс-метку Serializable, в противном случае, при попытке сериализовать объект будет выброшено исключение java.io.NotSerializableException.
Так же все атрибуты и подтипы сериализуемого класса должны быть сериализуемы. Если класс предок был несереализуемым, то этот суперкласс должен содержать доступный (public, protected) конструктор без параметров для инициализации полей.
Что означает ключевое слово transient?
В Java существует специальное ключевое слово transient с помощью которого
можно указать поля, которые не должны подвергаться сериализации (например,
поля, которые могут быть выведены или кэш)
Расскажите про Externalizable?
java.io.Externalizable интерфейс, который подобен java.io.Serializable но с настраиваемыми механизмами для выполнения сериализации (вам необходимо реализовать readExternal а также writeExternal методы на вашем классе). Это дает вам возможность обойти узкое место производительности отражения.
Статические поля поля можно сериализовать, final поля не сериализуются (из-за вызова конструктора по умолчанию)
В чем разница между IO и NIO?
IO - потокоориентированный, блокирующий (синхронный) ввод/вывод.
Потокоориентированный ввод/вывод подразумевает чтение/запись из потока/в поток одного или нескольких байт в единицу времени поочередно. Данная информация нигде не кэшируются. Таким образом, невозможно произвольно двигаться по потоку данных вперед или назад. Если мы хотим произвести подобные манипуляции, нам придется сначала кэшировать данные в буфере.
Потоки ввода/вывода (streams) в Java IO являются блокирующими. Это значит, что когда в потоке выполнения (tread) вызывается read() или write() метод любого класса из пакета java.io.*, происходит блокировка до тех пор, пока данные не будут считаны или записаны. Поток выполнения в данный момент не может делать ничего другого.
Классы потоков ввода\вывода лежат в java.io
———————————————————————————–
NIO - Буфер-ориентированный, Неблокирующий (асинхронный) ввод/вывод, Селекторы.
Подход, на котором основан Java NIO немного отличается. Данные считываются в буфер для последующей обработки. Мы можем двигаться по буферу вперед и назад. Это дает немного больше гибкости при обработке данных. В то же время, нам необходимо проверять содержит ли буфер необходимый для корректной обработки объем данных. Также необходимо следить, чтобы при чтении данных в буфер вы не уничтожили ещё не обработанные данные, находящиеся в буфере.
Неблокирующий режим Java NIO позволяет использовать один поток выполнения для решения нескольких задач вместо пустого прожигания времени на ожидание в заблокированном состояний. Наиболее частой практикой является использование сэкономленного времени работы потока выполнения на обслуживание операций ввода/вывода в другом или других каналах.
Классы лежат в java.nio.
Селекторы
Селекторы в Java NIO позволяют одному потоку выполнения мониторить несколько каналов ввода. Мы можем зарегистрировать несколько каналов с селектором, а потом использовать один поток выполнения для обслуживания каналов, имеющих доступные для обработки данные, или для выбора каналов, готовых для записи.