Обработка исключений Работа с файлами Лекция 8
Обработка исключений Работа с файлами Работа с файловой системой Операции с потоками
Возвращаемое значение Не всегда возможно ( конструкторы ) Не сразу проявляется Непонятно, что конкретно произошло Усложняет код Глобальная переменная Не проходит в многопоточной среде Вызов определенной функции или завершение программы Не проходит, если библиотеки независимы Обработка исключений
Ошибке ставится в соответствие некоторый объект – исключение (exception) System.Exception Объект - исключение должен иметь тип, который является потомком System.Exception При возникновении ошибочной ситуации генерируется ( выбрасывается ) исключение if(j 3) throw throw new IndexOutOfRangeException(); Прерывается обычный ход выполнения операторов Если нет обработчика исключения, то приложение будет аварийно завешено.
Блок обработки исключений имеет следующий вид :try { // Код, требующий корректного восстановления или очистки ресурсов } [catch [catch [(exception_type1 [name_1])] { // Код восстановления, после возникновения исключения exception_type1 } … catch … catch(exception_typeN [name_N]) { // Код восстановления, после возникновения исключения exception_typeN ] } ] [finally { // Код очисти ресурсов, после операций в блоке try // Этот код выполняется всегда, вне зависимости от наличия исключения ] } ] Блок try – обязательный Блоки catch и finally могут отсутствовать, однако хотя бы один из них должен присутствовать
После генерации исключения рассматриваются блоки в порядке возрастания удаленности Сначала смотрится статическая вложенность – вложенность блоков кода ( внутри метода ) Затем смотрится динамическая вложенность – порядок вызовов в стеке В них просматриваются все обработчики (catch) сверху вниз. Если тип сгенерированного исключения – потомок типа, указанного в блоке catch, блок catch выбирается для обработки этого исключения Если найден блок catch, соответствующий исключению, то до выполнения кода в блоке catch выполняются все внутренние блоки finally ( если имеются ). После обработки исключения выполнение в каком - то блоке catch, все остальные блоки catch игнорируются. Блок finally выполняется всегда при выходе из блока обработки исключения, независимо от того возникло ли исключение или нет, обработано ли оно или нет. Блок finally выполнится всегда. Если исключение возникло и обработано, то выполнение продолжается с кода, следующего за обработавшим исключение try-catch-finally блоком ( сначала выполнив блок finally) Если при возникновении исключения не находится подходящий блок catch, т. е. исключение остается не обработанным, то выполнение программы аварийно завершается.
В C# 6 добавлена возможность фильтрации исключенийtry { // Код, требующий корректного восстановления или очистки ресурсов } [catch when (condition) [catch (Exception ex) when (condition) { // Код восстановления, после возникновения исключения Exception при условии выполнения выражения condition } … catch … catch (Exception ex) // Код восстановления, после возникновения исключения Exception при условии, что не подошли предыдущие блоки catch (с их условиями) ] } ] [finally { // Код очисти ресурсов, после операций в блоке try // Этот код выполняется всегда, вне зависимости от наличия исключения ] } ]
Способы восстановления после исключения try { // Читаем файл } catch (FileNotFoundException e) { throw e; } catch (FileLoadException) { throw; } catch (IOException e) { throw new MyException (" Что - то не так при работе с файлом ", e); } catch (Exception) { // Все ок. Не генерируем новое исключения } Еще раз сгенерировать то же исключение для передачи информации о нем коду, расположенному выше в стеке ; Сгенерировать исключение другого типа для передачи дополнительной информации коду, расположенному выше в стеке ; Позволить программному потоку выйти из блока catch естественным образом
Базовый класс для всех исключений Message Поле Message – описание возникшего исключения Source Поле Source – ссылка на объект, сгенерировавший исключение, или на сборку, в которой возникло исключение StackTrace Поле StackTrace – стек вызовов InnerExeption Поле InnerExeption – предыдущее исключение ( при дальнейшей передачи исключения ) При создании своего типа исключения необходимо наследоваться от типа System.Exeption
Исключения
Обработка исключений Работа с файлами Работа с файловой системой Операции с потоками
Пространство имен System.IO Работа с файловой системой DriveInfo Диски : DriveInfo DirectoryInfoDirectoryFileSystemInfo Папки : DirectoryInfo, Directory, FileSystemInfo FileFileInfoFileSystemInfo Файлы : File, FileInfo, FileSystemInfo Работа с путями Path Path Наблюдение за изменениями в файловой системе FileSystemWatcher FileSystemWatcher Работа с потоками ( чтение / запись файла ) Stream Stream, производные от него и классы обертки
Два способа работы : File, Directory – статические классы FileInfo, DirectoryInfo Многие методы похожие FileSystemInfo Базовый для FileInfo и DirectoryInfo DriveInfo Информация о диске Не связан с FileSystemInfo
Экземпляр представляет один диск DriveInfo drive = new DriveInfo("c"); DriveInfo drive = new Информация о диске системы Name Name – имя диска DriveType DriveType – тип диска. Например : Fixed, CDRom IsReady IsReady – готов ли к использованию ( например для CD Rom) VolumeLabel VolumeLabel – метка тома DriveFormat DriveFormat – тип файловой системы TotalSize TotalSize – размер диска AvailableFreeSpace AvailableFreeSpace – размер свободного места … Получение всех дисков GetDrives() Статически метод GetDrives() DriveInfo[] drives = DriveInfo.GetDrives();
Абстрактный класс Базовый класс для DirectoryInfo и FileInfo Свойства файла / папки Name Name – название файла, папки FullName FullName – полное имя, т. е. с полным путем Extension Extension - расширение Exists() Exists() – существует ли такой файл / папка CreationTimeLastAccessTime CreationTime, LastAccessTime – время создания / последнего доступа ( изменения ) Attributes Attributes - атрибуты ( только на чтение ) …
DirectoryInfo Экземпляр DirectoryInfo представляет одну папку файловой системы Наследник от FileSystemInfo Создание объекта ( но не физической папки на диске ) DirectoryInfo windowsFolder = new Получение информации о файлах и папках GetDirectories() GetDirectories() – получение подпапок. Возможен поиск по шаблону и поиск во всех дочерних папках DirectoryInfo[] folders = GetDirectories(); DirectoryInfo[] folders = di.GetDirectories(my*); DirectoryInfo[] folders = di.GetDirectories(my*, SearchOption.AllDirectories); GetFiles() GetFiles() – получение файлов FileInfo[] files = folder.GetFiles(); FileInfo[] files = folder.GetFiles("*.txt, SearchOption.TopDirectoryOnly); GetFileSystemInfos() GetFileSystemInfos() – получение всех файлов / папок FileSystemInfo[] fsi = folder.GetFileSystemInfos(); Операции с папками Create() Create() – создание папки по текущему объекту DirectoryInfo new CreateSubdirectory() CreateSubdirectory() - создание подпапки текущего каталога Delete() Delete() – удаление текущей папки MoveTo () MoveTo () – перемещение текущей папки Directory Класс Directory имеет практически такие же методы, но в статическом исполнении Directory.CreateDirectory(path);
FileInfo Экземпляр FileInfo представляет один файл файловой системы Наследник от FileSystemInfo Создание объекта ( но не физического файла на диске ) FileInfo file = new FileInfo(c:\\test.txt); Свойства ( в добавление к свойствам FileSystemInfo) DirectoryDirectoryName Directory, DirectoryName – папка DirectoryInfo или полное имя папки ( с полным путем ) IsReadOnly IsReadOnly – файл только для чтения Length Length – размер файла в байтах Операции с файлами целиком Create()CreateText() Create(), CreateText() – создание файла CopyTo() CopyTo() – копирование файла Delete() Delete() – удаление текущего файла MoveTo () MoveTo () – перемещение текущего файла Операции с содержимым файла Create()CreateText()OpenRead()OpenText()OpenWrite()AppendText() Create(), CreateText(), OpenRead(), OpenText(), OpenWrite(), AppendText() File Класс File имеет практически такие же методы, но в статическом исполнении File.Delete(c:\\myText.txt);
Статический класс Работа с путями GetPathRootGetDirectoryNameGetFullPathGetFileName GetFileNameWithoutExtensionGetExtension GetPathRoot, GetDirectoryName, GetFullPath, GetFileName, GetFileNameWithoutExtension, GetExtension Комбинирование путей CombineChangeExtension Combine, ChangeExtension Проверки GetInvalidPathCharsGetInvalidFileNameCharsIsPathRootedHasExtension GetInvalidPathChars, GetInvalidFileNameChars, IsPathRooted, HasExtension Работа с временными папками GetTempPath GetTempFileName GetTempPath, GetTempFileName Не изменяет сами объекты, т. е. не переименовывает и не перемещает ( исключение GetTempFileName - создаёт физически файл на диске ) Не проверяет наличие объектов физически Проверяет валидность задания путей. Например проверяет допустимость символов Полезным может быть также статический класс Environment
Слушает сообщения об изменениях в файловой системе и генерирует события Настройка : Path Path – папка за изменениями которой нужно следить Filter Filter – задает фильтр объектов за которыми следить NotifyFilter NotifyFilter – задает за какими изменениями следить (Attributes, CreationTime, DirectoryName, FileName, LastAccess, LastWrite, Security, Size) EnableRaisingEvents Начало слежения – установка свойства EnableRaisingEvents = true Генерирует события ChangedCreatedDeletedRenamed Changed, Created, Deleted, Renamed
Работа с файлами каталогами
Класс Stream Представляет файл, порт, область памяти и т. д. как поток байт Абстрактный класс Запись, чтение, перемещение указателя Реализация конкретных потоков в наследниках Классы обертки. …Reader / ….Writer Чтение из / запись в поток BinaryReader/BinaryWriter – бинарные чтение / запись StreamReader/StreamWriter – текстовые чтение / запись Понятие кодировки (Encoding)
Возможности CanRead – можно ли читать CanWrite – можно ли писать CanSeek – можно ли двигать курсор Чтение int Read(byte[] buffer, int offset, int count) Запись void Write(byte[] buffer, int offset, int count) Текущая позиция long Position {get; set; } Перемещение long Seek(long offset, SeekOrigin origin); Закрытие потока void Close() void Dispose()
Stream PipeStream Поток данных из именованных каналов FileStream поток из файла MemoryStream поток из памяти SqlFileStream NetworkStream поток из сети UnmanagedMemoryStream поток неуправляемых данных …
CryptoStream CryptoStream – предоставляет шифрование потока BufferedStream BufferedStream – добавляет буферизацию GZipStreamDeflateStream GZipStream, DeflateStream – предоставляют возможность сжатия потока BinaryReader/BinaryWriter StreamReader/StreamWriter BinaryReader/BinaryWriter, StreamReader/StreamWriter – предоставляют удобные способы чтения / записи в поток
Классы обертки. Оборачивают конкретный поток Бинарный доступ к потоку Чтение / запись встроенных типов ReadXXX() / WriteXXX() XXX = Int32, Single, Double, … « Подсмотреть » следующий символ PeekChar() Кодировка по умолчанию UTF8
Классы обертки. Оборачивают конкретный поток Текстовый доступ к потоку Чтение / запись строк ReadLine() – чтение строки ReadToEnd() – сразу весь файл Write() – запись строки WriteLine() – запись строки + символ новой строки Параметры аналогичны функциям консоли
System.Text.Encoding Определяет преобразование char (Unicode) byte [] Encoding GetEncoding() получает кодировку по Имени : GetEncoding(windows-1251) Номеру : GetEncoding(1251) Использование : StreamReader sr = new StreamReader(stream, Encoding.Unicode);
TextReader/TextWriter – базовые классы StreamReader/StreamWriter – из потока StringReader/StringWriter – из строки Стандартные потоки Console.In – поток ввода Console.Out – поток вывода Console.Error – поток ошибок
Текстовый ввод - вывод