Similar presentations:
2.4
1. Исключения и работа с файлами
Рожков Константин ОлеговичИнженер-программист в «Диасофт»
2.
Ошибки в программахДавайте рассмотрим код ниже:
Как вы думаете, что может случиться во время ввода пользователем
значения в консоли?
2
3.
Ошибки в программеНапример, при вводе пользователем значения можно
написать не число, а строку (например “abrakadabra”). Во
время работы программы такая ошибка ввода приведет к
немедленному ее завершению.
3
4.
Читаем выброшенное исключениеException in thread "main" java.util.InputMismatchException:
Это сообщение об ошибке указывает на то, что в программе
возникло исключение типа InputMismatchException. Это
означает, что ввод, считываемый сканером, не соответствует
ожидаемому типу данных.
4
5.
Читаем выброшенное исключениеat java.base/java.util.Scanner.throwFor(Scanner.java:939)
Эта часть сообщения указывает на то, что исключение
было сгенерировано в методе throwFor класса Scanner в
файле Scanner.java на строке 939. Этот метод используется
для генерации исключений в классе Scanner.
5
6.
Читаем выброшенное исключениеat java.base/java.util.Scanner.next(Scanner.java:1594):
Следующая строка указывает на метод next класса Scanner в
файле Scanner.java на строке 1594. Метод next используется
для чтения следующей строки из ввода.
6
7.
Читаем выброшенное исключениеat java.base/java.util.Scanner.nextInt(Scanner.java:2258):
Здесь указан вызов метода nextInt класса Scanner в
файле Scanner.java на строке 2258.
Метод nextInt предназначен для чтения следующего
целого числа из ввода.
7
8.
Читаем выброшенное исключениеat java.base/java.util.Scanner.nextInt(Scanner.java:2212):
Это также вызов метода nextInt класса Scanner, но в этот
раз в файле Scanner.java на строке 2212. Это также
относится к чтению целого числа из ввода.
8
9.
Читаем выброшенное исключениеAt lesson8_ExceptionsFiles.ExceptDemo.main(ExceptDemo.java:10):
Последняя строка указывает на то, что исключение было
сгенерировано
в
методе
main
класса
ExceptDemo
в
файле ExceptDemo.java на строке 10. Именно здесь происходит чтение
целого числа, которое не соответствует ожидаемому формату.
9
10.
Вывод из чтения исключенияИсключение java.util.InputMismatchException возникает, когда следующая
строка не соответствует ожидаемому шаблону ввода. В нашем случае
есть проблема с чтением int с помощью Scanner.nextInt() в вашем
файле ExceptDemo.java на строке 10.
Каждая строка в сообщении об ошибке исключения представляет собой
метод в стеке вызовов (stack trace).
10
11.
Вывод из чтения исключенияСтек вызовов показывает последовательность методов, которые были
вызваны в момент возникновения исключения.
Каждая строка указывает на конкретный метод в коде, где исключение
было сгенерировано, и обычно включает имя класса, имя метода и
номер строки кода.
На практике часто стоит обращать внимание на первую строчку, чтобы
понять, какое исключение выброшено и на последнюю – где как раз есть
ссылка на наш код: ExceptDemo.java:10
Кликнув на ссылку мы сразу перейдем к месту, где она возникла
11
12.
Ошибки в программеЗадача программиста — уметь предвидеть появление
ошибок и правильно их обрабатывать.
Например, в одних случаях необходимо завершать работу
программы, а в других — продолжать ее выполнение и
запрашивать ввод корректных данных.
12
13.
ТерминологияВ языке Java ошибки в программах называются исключительными
ситуациями или исключениями (Exception).
Действие, которое означает появление исключения или создание
исключительной ситуации при работе программы, в Java принято
называть выбросом исключения (throws Exception).
А способы обработки исключительной ситуации — называют
перехватом исключения (catch Exception)
13
14.
Обработка исключительной ситуацииДобавим в нашу программу обработку исключения и выведем
Пользователю сообщение об ошибке ввода.
14
15.
Обработка исключительной ситуацииВ случае ошибки результат работы будет наше сообщение:
Мы обработали только один тип исключений — InputMismatchException.
Такой тип ошибок означает несоответствие ввода, как в нашем примере: мы
ожидали ввода числа, а пользователь ввел строку.
Далее подробнее рассмотрим другие исключения и научимся создавать свои
собственные. Существует целая иерархия исключений, и все они
наследуются от базового класса Throwable
15
16.
Иерархия исключенийThrowable
Error
RuntimeException
Exception
IOException
SQLException
16
17.
Иерархия исключенийБазовый класс всех исключений в Java —
это класс Throwable, фактически от него
наследуются все ошибочные ситуации.
17
18.
Иерархия исключений — ErrorОшибки работы виртуальной машины Java и ее окружения.
Error
VirtualMachineError
UnknownError
OutOfMemoryError
ThreadDeath
StackOverflowError
VirtualMachineError является суперклассом всех ошибок, выбрасываемых JVM,
связанных с работой самой виртуальной машины. Эти ошибки обычно вызваны
внутренними сбоями в JVM, которые являются фатальными и не могут быть
обработаны приложением.
ThreadDeath - это специальная ошибка, которая может быть брошена в потоке
для прерывания его выполнения. Когда ThreadDeath бросается в поток, это
приводит к тому, что поток тихо завершает свою работу без выполнения
блоков finally или других завершающих действий. Обычно ThreadDeath не
должен перехватываться и обрабатываться, так как его цель - просто завершить
18
поток.
19.
Иерархия исключений — VirtualMachineErrorОшибки работы виртуальной машины Java и ее окружения.
VirtualMachineError
UnknownError
OutOfMemoryError
StackOverflowError
UnknownError - выбрасывается, когда происходит неизвестное, но серьезное
исключение в Java Virtual Machine
OutOfMemoryError - это ошибка, которая возникает, когда виртуальная машина
Java не может выделить достаточно памяти для создания нового объекта, и это
может произойти, например, при исчерпании памяти кучи.
StackOverflowError - это ошибка, которая возникает, когда стек вызовов методов
переполняется из-за слишком глубокой рекурсии или из-за выделения слишком
большого объема локальной памяти для методов.
19
20.
Иерархия исключений — ExceptionException
RuntimeException
SQLException
IOException
EOFException
ArithmeticException
ClassCastException
FileNotFoundException
NullPointerException
SocketException
NoSuchElementException
Непроверяемые
Ошибки, связанные с работой приложения.
Проверяемые
20
21.
Иерархия исключенийRuntimeException
ClassCastException
ArithmeticException
NoSuchElementException
NullPointerException
RuntimeException в Java является подклассом Exception, который представляет
непроверяемые исключения, которые могут возникнуть во время выполнения
программы. Как непроверяемое исключение, RuntimeException и его подклассы не
требуют явного обработчика или объявления в блоке throws.
Непроверяемые
факторов
исключения
как
правило
возникают
вследствие
внешних
21
22.
Иерархия исключений — ExceptionRuntimeException
ClassCastException
NoSuchElementException
ArithmeticException
NullPointerException
ClassCastException - это исключение в Java, которое возникает при попытке
приведения объекта к типу, который он фактически не является. Например, если
вы пытаетесь привести объект к типу, который не является его
родительским классом или интерфейсом.
NoSuchElementException - это исключение в Java, которое указывает на то, что в
в списке запрашиваемый элемент не существует.
NullPointerException - это исключение в Java, которое указывает на попытку
доступа к члену объекта или вызову метода у переменной, которая равна null
ArithmeticException - это исключение в Java, которое возникает при выполнении
арифметических операций, таких как деление на ноль или переполнение для
определенного типа данных
22
23.
Все вместеThrowable
Error
ThreadDeath
VirtualMachineError
UnknownError
Exception
SQLException
RuntimeException
ArithmeticException
IOException
ClassCastException
EOFException
NullPointerException
SocketException
OutOfMemoryError
StackOverflowError
FileNotFoundException
NoSuchElementException
23
24.
Checked/unchecked исключения?Исключения делятся на два типа:
Checked (проверяемые) — исключения, которые обязательно нужно
обработать или указать в описании метода, что в нем может возникнуть
такого типа ошибка, если это не сделать, то компилятор не скомпилирует код
и вернет ошибку компиляции. Это все исключения, наследуемые от Throwable
и Exception.
Unchecked (непроверяемые) — исключения, которые не обязательно
обрабатывать, но они могут возникнуть во время выполнения программы. Это
все исключения, наследуемые от Error и RuntimeException.
24
25.
Почему нельзя просто сделать всепроверяемыми?
Гибкость кода: Непроверяемые исключения не требуют явного объявления
или обработки, что делает код более лаконичным и позволяет более гибко
управлять исключениями в некоторых случаях.
Меньше кода: В случае непроверяемых исключений не нужно использовать
блоки try-catch или объявлять их в сигнатуре метода, что сокращает объем
кода.
Исключения времени выполнения: Некоторые исключения, такие
как NullPointerException, обычно возникают из-за ошибок программирования и
не могут быть предугаданы на этапе компиляции.
Непроверяемые исключения зависят от внешних факторов, которые
трудно предугадать.
Однако, использование слишком многих непроверяемых исключений может
сделать код менее надежным и усложнить его отладку. Поэтому важно разумно
подходить к выбору между проверяемыми и непроверяемыми исключениями в
25
зависимости от конкретной ситуации.
26.
Способы обработки исключений1. Непроверяемые можно просто не обрабатывать
2. Использовать операторы try/catch/finally
3. Объявить в сигнатуре метода* throws
4. Выбросить ошибку в коде throw new Exception
26
27.
Не обрабатывать непроверяемыеисключения
Рассмотрим пример. Ниже программа производит деление на ноль:
При делении на ноль возникнет ошибка ArithmeticException — этот класс
исключения наследуется от RuntimeException и является unchecked (компилятор
не будет проверять во время процесса компиляции, обрабатывается это
исключение или нет).
27
28.
2. Использовать операторы try/catch/finallyВ Java есть три ключевых слова для обработки исключений:
try — используется для отметки начала блока кода, который потенциально
может привести к исключению и ошибке;
catch — используется для отметки начала блока кода, предназначенного для
перехвата и обработки исключений;
finally — используется для отметки начала блока кода, который является
дополнительным.
Блоки catch можно располагать друг за другом.
Блок finally помещается после последнего блока catch. finally является
необязательным, но если в программе требуется выполнить какой-то код, в
независимости от того, появилось исключение или нет, надо использовать блок
finally.
Обычно в этом блоке происходит закрытие и освобождение ресурсов (файла,
сетевого соединения и т.д.).
28
29.
2. Использовать операторы try/catch/finallyРассмотрим программу ввода двух чисел и будем перехватывать исключение
деления на ноль. Мы обернули «опасный код» операторами try/catch.
В блок try поместили весь код, который может вызвать ошибку, а в блок
catch — действие, которое хотим выполнить при возникновении ошибки.
29
30.
2. Использовать операторы try/catch/finallyВ нашем примере используется класс Scanner, который может работать не
только с консолью, но и с файлами и другими ресурсами, требующими
принудительного закрытия.
Поэтому независимо от того, возникнет ошибка или нет, нужно всегда
выполнять блок кода finally, чтобы закрыть соединение.
30
31.
Использовать операторы try/catch/finallyЕсли мы используем в блоке try/catch какой-либо внешний ресурс (читаем файл,
используем scanner), важно после использования закрыть канал доступа к этому
ресурсу и освободить его, например, вызвав метод close().
Если ресурсы не закрывать, это может привести к утечкам памяти или к тому,
что ресурсы будут заблокированы для других процессов, что в конечном итоге
может вызвать ошибки в работе программы.
Утечка памяти может проявиться в форме непредсказуемого поведения
программы, например, программы могут начать работать медленнее из-за
неэффективного использования памяти или в конечном итоге могут привести к
исчерпанию памяти и аварийному завершению работы программы.
31
32.
Использовать операторы try/catch/finallyМожно располагать несколько операторов catch друг после друга.
Изменим предыдущий пример и будем считывать из консоли строковые
значения. При этом у нас может возникнуть исключение NoSuchElementException
32
33.
Использовать операторы try/catch/finallyЕсли мы знаем, что действия в блоке catch будут одинаковы при разных
исключениях, то можем их объединить в один блок с помощью оператора “|”.
В данном случае, будет сложнее определить, что пользователь сделал не так.
34.
Использовать операторы try/catch/finallyНо можно, например, вывести в консоль информацию об ошибке.
35.
Использовать операторы try/catch/finallyЕсли мы хотим ловить все исключения, наследуемые от одного общего
класса (как было в примере выше — RuntimeException), можем указать
только его в качестве аргумента для перехвата исключения.
35
36.
Использовать операторы try/catch/finallyЕсли при описании исключений указать класс-родитель раньше, то блок
с исключением,
следующий после него, не будет вызван никогда (блок с
.
ArithmeticException не будет вызван):
Но обратное расположение допустимо и часто используется, с начала в
коде описывается класс-наследник, а за ним более общий (класс родитель)
36
37.
Объявить в методе throwsЕсли какой-либо метод в программе может выбросить проверяемое исключение,
то компилятор потребует от нас обязательно его обработать (с помощью блоков
try/catch) или объявить возможность возникновения исключения при описании
метода. После завершения описания аргументов нужно добавить оператор
throws:
37
38.
Объявить в сигнатуре метода throwsЧерез запятую можно перечислить исключения, которые могут возникнуть в
методе:
Можно также объединить родительским исключением:
Исключения, объявленные с использованием оператора throws, будут
выброшены в консоль и выведены на экран.
38
39.
Разница между try-catch и throwsМожно провести параллель с дорожными
знаками.
throws – как предупреждающий знак для
других разработчиков о том, что данный метод
может выбросить исключение, которое нужно
будет обработать (или так же предупредить об
исключении в своем методе)
try-catch – это как объездная дорога, в случае
обнаружения неполадки на основной.
39
40.
Объявить в сигнатуре метода throwsПример объявления проверяемого исключения для метода преобразования
даты, введенной пользователем:
40
41.
Объявить в сигнатуре метода throwsПример объявления проверяемого исключения для метода преобразования
даты, введенной пользователем:
Мы можем в методе main «установить предупреждающий знак» как в этом
примере или «проложить запасной путь» как в прошлом.
41
42.
Выбросить ошибку в коде throw new ExceptionВ случае, если нам требуется прекратить работу программы (например,
пользователь ввел некорректные данные), мы можем сами инициировать
создание и выброс исключения.
Для выброса исключения нужно в методе объявить оператор throw и создать
исключение, например: throw new Exception ("Сообщение"):
42
43.
Создать свой тип исключенияЧтобы создать свое исключение, нужно унаследовать свой класс от классаисключения. Для создания своего проверяемого исключения можно
наследоваться от классов Throwalbe или Exception, а для создания
unchecked exception — от класса RuntimeException.
К теме наследования мы еще вернемся на следующих занятиях.
43
44.
Создать свой тип исключенияТеперь попробуем выбросить свое исключение:
44
45.
ПрактикаНа примере задач из предыдущих занятий добавить в код обработку
исключений.
45
46.
ИтогиТеперь мы знаем иерархию исключений
Умеем читать stacktrace, чтобы выявить ошибку
Выбрасывать
исключения
в
коде,
ловить
ошибки,
обходить их в коде
Проверяемые/непроверяемые исключения
Как создать свой тип исключений
46
47.
Работа с файламиКласс File, определённый в пакете java.io, управляет информацией о
файлах и каталогах. Файлы и каталоги отличаются друг от друга в
операционной системе, но в Java они описываются одним классом File
Попробуем создать свой файл и папку
47
48.
Работа с файламиВажно, инициализация переменных dir и файл в java не приводит к созданию
папки и файла. Нужно воспользоваться соответствующими методами:
mkdir()
createNewFile()
Блок try-catch необходим, так как метод createNewFile() может пробросить
исключение, если путь к файлу будет некорректен
48
49.
Получение информации о файлеПопробуем вывести информацию нашем новом файле greetings.txt
49
50.
Получение информации о файлеИнформация о состоянии файла
50
51.
Список объектов каталогаДобавим еще 2 файла в каталог и выведем по ним информацию
51
52.
Понятие потокаПоток - применительно к работе с файлами, это последовательность
данных, которая используется для чтения или записи информации. В Java
может быть определен поток, который связан с файлом, через который мы
сможем проводить чтение или запись файла.
Объект, из которого можно считать данные, называется потоком ввода.
Объект, в который можно записывать данные, - потоком вывода.
Например, если надо считать содержание файла, то применяется поток
ввода, а если надо записать в файл - то поток вывода.
52
53.
Классы для работы с потокамиДля работы с потоками байтов* используются классы:
FileInputStream — последовательное чтение из файла байтов (byte)
FileOutputStream — последовательная запись в файл байтов (byte)
Для работы с потоками символов** используются классы:
Reader — последовательное чтение из него символов (char)
Writer — последовательную запись в него символов (char)
53
54.
Запишем в файл строкуДля создания объекта FileOutputStream передадим в качестве параметра путь
к файлу для записи.
Если такого файла нет, то он автоматически создаётся при записи.
Для записи в файл используем метод write(), который принимает
преобразованную в массив байтов строку.
После использования потока его необходимо закрыть для освобождения
ресурса. Используем метод close()
54
55.
Используем try с ресурсамиДля автоматического закрытия файла и освобождения ресурса объект
FileOutputStream создаётся с помощью конструкции try...catch с ресурсами,
где в круглых скобках () передаем сам ресурс, который требуется закрыть
после выполнения блока кода в фигурных скобках {}. Тогда метод close() не
нужен.
Результат этого и прошлого примера – успешная запись строки в указанный
файл:
55
56.
Чтение из файла:Для считывания данных из файла предназначен класс FileInputStream
Для создания объекта FileInputStream можно передать в качестве параметра
путь к считываемому файлу.
Если файл не может быть открыт (например, по указанному пути такого файла
не существует), то генерируется исключение FileNotFoundException
Вывод в консоль будет:
56
57.
Сделаем явное приведение:Вывод в консоль будет
57
58.
FileWriter для записи строк:Класс FileWriter используется для записи текстовых файлов. В параметр
передается путь к файлу. Если файла нет, то он будет создан. Либо можно
передать сразу объект класса File
Получаем файл с содержимым:
58
59.
FileWriter для записи строк:Мы можем добавить второй параметр со значением false, тогда данные
будут перезаписаны в каждом вызове программы.
Получаем файл с содержимым. Наши предыдущие записи были удалены,
потому что мы добавили в FileWriter второй параметр false.
59
60.
FileReader для чтения файлов:В параметр так же передаем путь к файлу или объект File
Вывод в консоль:
60
61.
BufferedReader для чтения файлов:Класс BufferedReader считывает данные из входного источника во внутренний
буфер, что уменьшает количество операций ввода-вывода и делает считывание
более эффективным. Кроме того, BufferedReader предоставляет методы, такие
как readLine(), для считывания строк текста, что упрощает считывание и
обработку текстовых данных.
Сначала мы создали объект класса FileReader, а затем поместили его как
параметр для создания объекта BufferedReader. Это нам позволит считывать
файл построчно, используя метод readLine().
61
62.
ПрактикаРеализуйте метод, который получает доступ к элементу по индексу в массиве и
обрабатывает исключение выхода за границы массива.
.
.
62
63.
ПрактикаИспользуя класс File, создайте папку resources и поместить в нее файл text1.txt.
Наполнить файл 5 строками.
Напишите функцию, открывающую файл text1.txt, выводящую в терминал n
последних сток.
Значение n следует получить от пользователя в консоли.
.
.
63
64.
ПрактикаСоздайте файл text2.txt.
Наполните файл 5 строками.
Напишите функцию, открывающую файл text2.txt и производящую конкатенацию
над всеми строками в файле.
Результат конкатенации необходимо вывести в терминал.
.
.
64
65.
ИтогиТеперь мы знаем что такое объект File в java
Как создавать папку и файл посредством кода
Умеем считывать информацию о файлах и папках
Записывать и считывать данные из файлов
65
programming