Файл: Разница в io при работе с файлом и директорией. Что делает метод available().docx

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

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

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

Добавлен: 04.12.2023

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

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

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



  1. В классе Thread определены семь перегруженных конструкторов, большое количество методов, предназначенных для работы с потоками, и три константы (приоритеты выполнения потока).

Метод run() выполняется при запуске потока. После определения объекта Runnable он передается в один из конструкторов класса Thread.

  1. Не нужно закрывать обычный Stream из Stream API.

Не нужно закрывать тот поток, который объявлен в try-with-resources

OutputStream – пустой метод close()










  1. Строки – неизменяемый объект, мы можем копировать их просто ссылаясь на них.

  2. Так как строки иммутабельны, клонировать их не обязательно (хотя можно). Хватит и клонировать только массив, а строки использовать те же

  3. При стандартной сериализации поля, имеющие модификатор static, не сериализуются. Соответственно, после десериализации это поле значения не меняет. При использовании реализации Externalizable сериализовать и десериализовать статическое поле можно, но не рекомендуется этого делать, т.к. это может сопровождаться трудноуловимыми ошибками. Поле с модификатором trainsent, будет равно null.

  4. flush (), очищает все потоки данных и полностью их записывает, а также дает новое пространство для новых потоков во временном расположении буфера. Но если буффер пустой (/ не попали данные через write) – то ничего записано не будет

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

  6. Переопределение метода clone() и реализация интерфейса Cloneable(); Использование конструктора копирования;
    Использовать для клонирования механизм сериализации.

Только объекты можно клонировать

  1. System.out/System.in – консольные потоки ввода вывода.

  2. Cканнер очень сильно проигрывает по быстродействию, он примерно в 1000 раз медленнее, чем BufferedReader. Но у сканнера уже впилены удобные функции по разбору текста на разные данные (целые числа, дробные числа, текст и тп), когда у bufferedreader-a их придется отдельно парсить.


Итог - если данных мало, то удобнее сканнер, если много или важна быстрота - то однозначно bufferedreader

  1. Класс File, определенный в пакете java.io, не работает напрямую с потоками. Его задачей является управление информацией о файлах и каталогах. Хотя на уровне операционной системы файлы и каталоги отличаются, но в Java они описываются одним классом File.

В зависимости от того, что должен представлять объект File - файл или каталог, мы можем использовать один из конструкторов для создания объекта:

File(String путь_к_каталогу)

File(String путь_к_каталогу, String имя_файла)

File(File каталог, String имя_файла)

Способы создания:

Использовать метод File.createNewFile(). Этот метод возвращает логическое значение
Если вы хотите создать новый файл и в то же время, если хотите записать в него некоторые данные, вы можете использовать метод записи FileOutputStream. В Java FileOutputStream является классом потока байтов. Чтобы записать данные в файл, вы должны преобразовать данные в байты, а затем сохранить их в файл.

Создание временного файла в java может потребоваться во многих сценариях, но в основном это происходит во время модульных тестов, где вы не хотите сохранять результаты. Создание с помощью java.io.File.createTempFile()




  1. Java не может удалять папки с данными в нем. Вы должны удалить все файлы перед удалением папки.

String[] entries = index.list();

for(String s: entries){

File currentFile = new File(index.getPath(),s);

currentFile.delete();

}

Тогда можно удалить папку с помощью index.delete()

  1. Он возвращает int, потому что, когда поток больше не может быть прочитан, он возвращает -1.

Если он вернул байт, то -1 не может быть возвращен, чтобы указать на отсутствие входных данных, потому что -1 является допустимым байтом. Кроме того, вы не можете возвращать значение выше 127 или ниже -128, потому что Java обрабатывает только подписанные байты.

Много раз, когда вы читаете файл, вам нужны неподписанные байты для вашего кода обработки.

  1. 255, так как обрезается до 8 битов

  2. System.out.println(Arrays.toString(bytes));

String str = new String(bytes,StandardCharsets.UTF_8);

Либо используя Reader

  1. Сканер может читать текст с любого объекта, который реализует интерфейс Readable. Если вызов базового метода Readable.read (java.nio.CharBuffer), доступного для чтения, генерирует IOException, то сканер предполагает, что достигнут конец ввода.


Похоже, что Scanner не имеет своего собственного буфера. Он использует буфер из базового объекта (который реализует Readable) и использует регулярные выражения для анализа.

  1. Клонирование — это процесс копирования объекта, то есть создания нового экземпляра путем копирования самого себя. 

Для реализации клонирования класс должен применить интерфейс Cloneable, который определяет метод clone. Реализация этого метода просто возвращает вызов метода clone для родительского класса - то есть класса Object с преобразованием к типу Person.

Кроме того, на случай если класс не поддерживает клонирование, метод должен выбрасывать исключение CloneNotSupportedException, что определяется с помощью оператора throws. В джава есть поверхностное копирование и глубокое

  1. В переводе на русский означает, что flush() вызывает чистку буфера вызывая метод реализованный в самой ОС поверх которой работает JVM. При этом даже отсутствие буфера в самом потоке не означает, что не будет использоваться в качестве буфера кэш диска на уровне ОСи или даже ниже. Использование flush() – хороший тон поскольку, девелопер не знает есть ли буфер на уровне ОС

  2. Декоратор — это структурный паттерн, который позволяет добавлять объектам новые поведения на лету, помещая их в объекты-обёртки.inputstream, bytearrayinputstream, stringbuilderinputstreams и так далее являются основанными элементами. Filterinputstream - это базовый класс для классов декораторов. Фильтр входных потоков (например, bufferedinput stream) может выполнять дополнительные функции при чтении потоков или записи в них. Он реализует все те же методы, что и InputStream, который лежит в нём, но позволяет к ним добавить доп. функционал. Конкретно его используют для какой-либо модификации данных из InputStream (т.е. фильтрации).

Адаптеры:

OutputStreamWriter мы легко «адаптирует» два интерфейса классов Writer и OutputStream друг другу.

Класс InputStreamReader — это классический адаптер, он адаптирует InputStream и Reader

  1. Клонирование – создает что-то новое на основе существующего.

Копирование - копирование с чего-то существующего на что-то другое (что также уже существует).

  1. Если вы хотите, чтобы буфер был сброшен, да, вызовите flush() перед вызовом close().


Несмотря на все другие ответы на обратное (но, как указано в некоторых комментариях), реализация java.io.OutputStream::close() по умолчанию не вызывает flush()

  1. Java IO (input-output) является потокоориентированным
    Java NIO (new/non-blocking io) – буфер-ориентированным.

  2. Static (если не сделали нужный static метод) и transient

  3. Когда Serializable класс имеет цепочку родителей, пока эти родители тоже Serializable, десериализация объекта идет от родителя к наследнику, в обход конструктора. Вместо него вызываются методы readObject (readObjectNoData). Но как только встречается первый предок, не реализующий интерфейс Serializable, инициализация для него возвращается в нормальное русло – вместо readObject вызывается конструктор без аргументов. Если такого конструктора нет, или он объявлен private, исполнение выбросит InvalidClassException.

При сериализации несериализуемые предки просто игнорируются.

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

  1.  Соответственно, если необходимо сериализовать объект с final полем необходимо использовать только стандартную сериализацию. Так как их невозможно десериализовать при использовании Externalizable, поскольку final поля должны быть инициализированы в конструкторе, а после этого в readExternal() изменить значение этого поля будет невозможно.

  2. При записи Serializable класса весь контроль над сериализацией достается JVM. С помощью определения специальных методов можно кастомизировать его части. Метод readObject при этом обычно начинается с вызова стандартной части сериализации – ObjectInputStream.defaultReadObject().

Интерфейс Externalizable расширяет Serializable и добавляет методы записи и чтения writeExternal и readExternal. Входной и выходной потоки-аргументы в них представлены более абстрактно чем в специальных методах – интерфейсами ObjectInput и ObjectOutput.

Этот интерфейс позволяет реализовать полностью свой механизм сериализации, стандартно запишется только идентификатор класса. Никакой автоматической работы с классом-родителем также не предусмотрено. Методы readObject и writeObject игнорируются. Ключевое слово transient эффекта на Externalizable не имеет.

Externalizable объект в отличие от Serializable десерализуется не в обход конструктора, так что должен иметь конструктор без аргументов.


  1. Метод close () закрывает соединение между программой и открытым файлом, чтобы закрыть ресурсы которые не могут не может очистить garbage collector, так как он не знает какие ресурсы есть помимо JVM.

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






  1. Адаптер и декоратор:

Декоратор также оборачивает некоторый класс и предоставляет такой же или расширенный интерфейс. Иногда декоратор называют "умным заместителем" (smart proxy). Т.е. декоратор может притворяться оригинальным классом и при этом расширять его функциональность.

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

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