• ,

Уровень 18: план уровня и доп. материалы

План уровня:
  • Знакомство с потоками: InputStream/OutputStream, FileInputStream, FileOutputStream
  • Знакомство с потоками
  • Знакомство с InputStream, OutputStream, Reader, Writer
  • Примеры работы с FileInputStream, FileOutputStream
  • BufferedInputStream, ByteArrayInputStream
  • Шаблон проектирования «Обертка» (Wrapper/Decorator)
  • Буфер и буферизация
  • Знакомство с StringBuilder

На этом уровне потоки ввода-вывода рассматриваются выборочно.
Дополнительное углубленное изучение будет на 31-32 уровнях.

Курс Java

Что еще можно посмотреть на досуге:
Декоратор или Wrapper/Обёртка
Ввод и вывод в Java
Обязательно прочтите еще раз мотивирующую статью

kharkovitcourses.blogspot.de/2012/08/module-java-io.html



Нашли классную ссылку к материалу данной темы? Добавьте ее сюда в виде комментария.
Возможно, именно Ваша ссылка поможет другому человеку стать программистом и улучшить свою жизнь!

Вернуться к плану обучения

Вернуться к обучению java онлайн на JavaRush

36 комментариев

SergeyKandalintsev
Лекция 18, урок 6 (лекция Эми о BufferedInputStream)
Приведенный пример обертки (класс CatWrapper как обертка над классом Cat)не скомпилируется т. к. конструктор CatWrapper(CatWrapper cat) не вызывает конструктор родительского класса Cat(String name).
mrANDERSON
И void в методе printName забыли. Но зато заставляет подумать когда код копируешь в ИДЕ :)
aleksandrov
Т.к сайт Wikijava.org сломался, решил для JavaRush попробовать восстановить Thinking in Java

вот ссылка на 16 урок(без картинок, где картинки взять незнаю)
wikijava.org.ua/index.php?title=%D0%93%D0%BB%D0%B0%D0%B2%D0%B0_16_Thinking_in_Java_4th_edition_Rebuild
masterSporta
Здравствуйте, товарищи! Было бы хорошо, если бы дали ссылки на рабочие сайты. Этот сайт, который заблокировался мне нравился, потому что там все глубоко объяснялось. У меня есть книжка «Философия java», но там код разобрать невозможно, т.е. возможно… опечатки много.
oleksandra
Очень хорошие видиолекции!!! Рекомендую смотреть
kharkovitcourses.blogspot.de/2012/08/module-java-io.html
larinje
спасибо! лекции действительно интересные!
Inquirer
Спасибо

Мне также помогла статья профФесора из Сингапурского Универстета:
Basic Input & Output (I/O)

и вообще у него есть другие достойные материалы:
programming notes
ZoomAll
Глава «Знакомство с потоками ввода-вывода» содержит некорректный пример:

Bernard_12
Он и не должен ничего выводить
ZoomAll
Глава «BufferedInputStream» содержит неточный текст:


BufferedInputStream декорирует FilterInputStream
Vash_the_Stampede
  • Vash_the_Stampede
  • 0
  • Комментарий отредактирован 2014-09-04 12:14:47 пользователем Vash_the_Stampede
«декорирует»)
maxim343
А что будет, если создать несколько потоков к одному файлу? Возможно ли это? и к чему это приведёт?
4joke
Можно провести эксперимент)
MindIbniM
Не вполне понятно как согласуется утверждение
Декоратор предусматривает расширение функциональности объекта без определения подклассов.
с примером из лекции. CatWrapper банально наследует Cat, тем самым позволяя расширять функциональность за счет полиморфизма — через переопределение методов. Тот же getName() можно вызвать с помощью super. Таким образом и кода получится меньше.
P.S. Оправданным остается вариант из Вики, то есть работа на уровне интерфейсов.
napeHb
Очень неудачная лекция и задачи в ней. Запутали совсем меня, пока тут не почитал. Во всех источниках, где читал, этот шаблон используется вместо наследования, а тут вместе — отсюда путаница в голове.
eger
  • eger
  • 0
Вторая ссылка: «Ввод и вывод в Java» — не рабочая.
404 Not Found
eNdiD
В самом начале 6 лекции 18 уровня:

Однако:

Как же так?
eNdiD
Дошло. В начале лекции имеется в виду наследование в более широком смысле.
eNdiD
  • eNdiD
  • 0
  • Комментарий отредактирован 2015-02-24 04:03:58 пользователем eNdiD
Однако, все же считаю, что задачи на применение декораторов неудачные. В них предлагается наследовать декорируемый класс, что в корне не соответствует паттерну декоратора. Декоратор может наследовать абстрактный класс, либо интерфейс, объединяющие декоратор с целевым классом. В случае же наследования класса, прийдется реализовывать конструктор суперкласса, что приведет к созданию лишнего экземпляра класса. Зачем? Я понимаю, что вы даете базу и предполагаете самостоятельное дальнейшее углубление в тему, но прошу, не стоит изначально давать некорректные примеры.
napeHb
Голову себе сломал с этими примерами и задачами из курса. Про этот паттерн пишут, что используется вместо наследования. А в этом курсе вместе с наследованием. Хотел тут уточнять уже, увидел ответ, который все разъяснил, спасибо.
Alejandro_Kolio
Друзья, хочу поделиться с вами еще одной ссылкой на видеолекцию.
Очень нравится как объясняет, да другие лекции из этой серии тоже бомба
Java. Работа с файловой системой (лекция 6)
Inspiron
не сказал бы что прям бобма, Головач, на мой взгляд лучше объясняет и примеры даёт более понятные
rhanza
Здравствуйте. Возник вопрос по материалам 18 уровня, а конкретно по главе 4 «InputStream/OutputStream».
Приведу кусок кода и текст урока:

public static void main(String[] args) throws Exception
{

 //Создаем поток-чтения-байт-из-файла

 FileInputStream inputStream = newFileInputStream("c:/data.txt");

 // Создаем поток-записи-байт-в-файл

 FileOutputStream outputStream = newFileOutputStream("c:/result.txt");


  byte[] buffer = new byte[1000];

 while (inputStream.available() >0) //пока есть еще непрочитанные байты

 {

  // прочитать очередной блок байт в переменную buffer и реальное количество в count

  int count =inputStream.read(buffer);

  outputStream.write(buffer, 0, count); //записать блок(часть блока) во второй поток

 }


 inputStream.close(); //закрываем оба потока. Они больше не нужны.

 outputStream.close();
}


Конкретнее вот эта часть:

outputStream.write(buffer, 0, count); //записать блок(часть блока) во второй поток


Получается, что мы получаем в int count — реальное количество прочитанных байт (например 328). Следовательно, для записи необходимо взять именно эту часть массива (т.е. buffer [0] — buffer [327]). С учетом нуля получается 328 элементов, которые нам и надо прочитать.
В итоге часть когда, мне кажется, должна выглядеть следующим образом:

outputStream.write(buffer, 0, count-1);


Прав ли я? Возможно я что-то не понимаю, прошу ответить.
igor_kr
Неправ!
Здесь:
from — номер ячейки, с которой нужно начинать читать
count — количество ячеек, которые нужно прочитать.
Не номер последней ячейки, а количество ячеек!!!
rhanza
Благодарю. Впредь буду читать javadoc :)
mrANDERSON
from — номер ячейки, с которой нужно начинать читать
точнее индекс массива.

При решении 3й задачи 5го уровня все сразу становится ясно. Тем более если предварительно заглянуть джавадок (но этот метод стандартно реализован, тут можно и не заглядывать).
mrANDERSON
Из лекции
flush при этом вызывается автоматически.
Но в спеке не сказано что flush() вызывется автоматически при вызове close(). К тому же Головач говорит что не вызывается — youtu.be/6YkGh8i2-go?t=1597. Подскажите, пожалуйста, кто точно знает(!) вызывается flush() автоматически при вызове close() или нет!??
Спасибо!

P.S. Спека — public void close()
throws IOException

Closes this output stream and releases any system resources associated with this stream. The general contract of close is that it closes the output stream. A closed stream cannot perform output operations and cannot be reopened.
boyarskiy
Походу лишним не будет. Согласно официальному оракловскому туториалу, какие-то классы вызывают flush() автоматически, а какие-то нет. Чтобы постоянно не лезть в мануал, думаю лучше взять за правило самому его вызывать перед close().

Flushing Buffered Streams

It often makes sense to write out a buffer at critical points, without waiting for it to fill. This is known as flushing the buffer.

Some buffered output classes support autoflush, specified by an optional constructor argument. When autoflush is enabled, certain key events cause the buffer to be flushed. For example, an autoflush PrintWriter object flushes the buffer on every invocation of println or format. See Formatting for more on these methods.

To flush a stream manually, invoke its flush method. The flush method is valid on any output stream, but has no effect unless the stream is buffered.

То есть PrintStream сам вызывает flush при каждом вызове println(), следоветельно его flush-ить перед закрытием нет смысла.
Что касается вопроса об автоматическом вызове flush после close, то явного ответа в документации лично я не нашёл (смотрел с JDK5 по JDK8), некотрые люди такое находили судя по записям со stackoverflow за 2012 год. Но тем не менее, на этом форуме отвечают, что вызов flush() перед close() это правила хорошего тона.
Есть книга по вводу-выводу в ява от O'Reilly за 2006 год, в ней автор утверждает, что close() вызывает flush() автоматически.
Ещё среди ораколовских туториалов видел пример, где перед close() вызывался flush().
Когда я тестировал на своей машине, то лично у меня FileOutputStream скидывал в файл один байт даже без flish() и close() — опять же, это может быть особенность linux-операционки и SSD харда.
На мой взгляд, эти два метода выполняют две разные функции. Flush — очищение буферов, close — корректное освобождение ресурсов. Так что вызвать flush() перед close() лишним не будет.
Как видно ситуация не однозначная, так что лучше перестраховаться. Это как парковка автомобиля — если не уверен, что тут можно стоять, то лучше встать в другом месте, и пусть оно будет дальше, но тебя 100% не заберут оттуда.
boyarskiy
Систематизация ввода-вывода Java.io.
anshelen
  • anshelen
  • 0
  • Комментарий отредактирован 2017-01-24 14:07:37 пользователем anshelen
Вот есть перевод хорошей статьи про кодировки (иногда помогает при работе с Reader, Writer)
Статья про кодировки
boyarskiy
Друзья, кто в курсе, подскажите как поступить. Вот ранее была дана ссылка не видеолекции Ивана Головоча по потокам. Она за 2013 год. Здесь дана ссылка на лекции по вводу-выводу, они за 2012 год. Как известно, у Ивана выложены записи курсов с одинаковой программой за разные периоды. Можно ли просматривать все темы из одного периода курсов, чтоб не скакать, или они по качесту отличаются, поэтому здесь и выкладывают из разных годов?
alexeyfrei
Вернулся назад почитать про IO и накнулся на такую вещь, которую в первый раз наверное даже не заметил. В части 6. код показывающий пример обертки:
class Cat
{
 private String name;
 public Cat(String name)
 {
  this.name = name;
 }
 public String getName()
 {
  return this.name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
}

И класс наследник от Cat

class CatWrapper extends Cat
{
 private Cat original;
 public CatWrapper (Cat cat)
 {
  this.original = cat;
 }

 public String getName()
 {
  return "Кот по имени " + original.getName();
 }

 public void setName(String name)
 {
  original.setName(name);
 }
}


Здесь, похоже, либо нужно явно описать конструктор без параметров в классе Cat либо в конструктор CatWrapper добаить super(cat.getName).
JuriMik
Мы передаём уже созданный экземпляр класса Cat в CatWrapper
alexeyfrei
  • alexeyfrei
  • 0
  • Комментарий отредактирован 2017-01-27 22:09:42 пользователем alexeyfrei
что-то я все равно не понимаю. Ведь конструктор базового класса вызывается автоматически, а т.к. в базовом классе определен конструктор с параметром, то и из наследника должен передаться параметр.
Я попробовал скомпилировать код в IDE и не вышло по выше озвученой причине. Что я делаю не так?
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.