Лекция 8 Обработка исключений Работа с файлами

advertisement
Лекция 8
Обработка исключений
Работа с файлами
 Обработка
исключений
 Работа с файлами
• Работа с файловой системой
• Операции с потоками

Возвращаемое значение
• Не всегда возможно (конструкторы)
• Не сразу проявляется
• Непонятно, что конкретно произошло
• Усложняет код

Глобальная переменная
• Не проходит в многопоточной среде

Вызов определенной функции или завершение
программы
• Не проходит, если библиотеки независимы

Обработка исключений



Ошибке ставится в соответствие некоторый объект –
исключение (exception)
Объект-исключение должен иметь тип, который является
потомком System.Exception
При возникновении ошибочной ситуации генерируется
(выбрасывается) исключение
if(j < 0 || j > 3)
throw new IndexOutOfRangeException();


Прерывается обычный ход выполнения операторов
Если нет обработчика исключения, то приложение будет
аварийно завешено.

Блок обработки исключений имеет следующий вид:
try
{
// Код, требующий корректного восстановления или очистки ресурсов
}
[catch [(exception_type1 [name_1])]
{
// Код восстановления, после возникновения исключения exception_type1
}
… 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 (Exception ex) when (condition)
{
// Код восстановления, после возникновения исключения Exception при
условии выполнения выражения condition
}
… 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 – описание возникшего исключения
Поле Source – ссылка на объект, сгенерировавший
исключение, или на сборку, в которой возникло
исключение
Поле StackTrace – стек вызовов
Поле InnerExeption – “предыдущее” исключение (при
дальнейшей передачи исключения)
При создании своего типа исключения необходимо
наследоваться от типа System.Exeption
Исключения
 Обработка
исключений
 Работа с файлами
• Работа с файловой системой
• Операции с потоками
Пространство имен System.IO
 Работа с файловой системой

• Диски: DriveInfo
• Папки: DirectoryInfo, Directory, FileSystemInfo
• Файлы: File, FileInfo, FileSystemInfo

Работа с путями
• Path

Наблюдение за изменениями в файловой системе
• FileSystemWatcher

Работа с потоками (чтение/запись файла)
• Stream, производные от него и классы обертки

Два способа работы:
• File, Directory – статические классы
• FileInfo, DirectoryInfo
• Многие методы похожие

FileSystemInfo
• Базовый для FileInfo и DirectoryInfo

DriveInfo
• Информация о диске
• Не связан с FileSystemInfo

Экземпляр представляет один диск
DriveInfo drive = new DriveInfo("c");
• DriveInfo drive = new DriveInfo(@"\\server\share");
•

Информация о диске системы
•
•
•
•
•
•
•
•

Name – имя диска
DriveType – тип диска. Например: Fixed, CDRom
IsReady – готов ли к использованию (например для CD Rom)
VolumeLabel – метка тома
DriveFormat – тип файловой системы
TotalSize – размер диска
AvailableFreeSpace – размер свободного места
…
Получение всех дисков
• Статически метод GetDrives()
 DriveInfo[] drives = DriveInfo.GetDrives();
Абстрактный класс
 Базовый класс для DirectoryInfo и FileInfo
 Свойства файла/папки

• Name – название файла, папки
• FullName – полное имя, т.е. с полным путем
• Extension - расширение
• Exists() – существует ли такой файл / папка
• CreationTime, LastAccessTime – время создания /
последнего доступа (изменения)
• Attributes - атрибуты (только на чтение)
• …



Экземпляр DirectoryInfo представляет одну папку файловой системы
Наследник от FileSystemInfo
Создание объекта (но не физической папки на диске)
•

DirectoryInfo windowsFolder = new DirectoryInfo(@"c:\Windows");
Получение информации о файлах и папках
•
•
•
GetDirectories() – получение подпапок. Возможен поиск по шаблону и поиск во всех дочерних папках

DirectoryInfo[] folders = GetDirectories();

DirectoryInfo[] folders = di.GetDirectories(“my*”);

DirectoryInfo[] folders = di.GetDirectories(“my*”, SearchOption.AllDirectories);
GetFiles() – получение файлов

FileInfo[] files = folder.GetFiles();

FileInfo[] files = folder.GetFiles("*.txt”, SearchOption.TopDirectoryOnly);
GetFileSystemInfos() – получение всех файлов/папок


Операции с папками
•
Create() – создание папки по текущему объекту DirectoryInfo


FileSystemInfo[] fsi = folder.GetFileSystemInfos();
new DirectoryInfo(@"c:\MyDir").Create();
•
CreateSubdirectory() - создание подпапки текущего каталога
•
Delete() – удаление текущей папки
•
MoveTo () – перемещение текущей папки
Класс Directory имеет практически такие же методы, но в статическом исполнении
•
Directory.CreateDirectory(path);



Экземпляр FileInfo представляет один файл файловой системы
Наследник от FileSystemInfo
Создание объекта (но не физического файла на диске)
•

FileInfo file = new FileInfo(“c:\\test.txt”);
Свойства (в добавление к свойствам FileSystemInfo)
Directory, DirectoryName – папка DirectoryInfo или полное имя папки (с полным путем)
• IsReadOnly – файл только для чтения
• Length – размер файла в байтах
•

Операции с файлами целиком
Create(), CreateText() – создание файла
• CopyTo() – копирование файла
• Delete() – удаление текущего файла
• MoveTo () – перемещение текущего файла
•

Операции с содержимым файла
•

Create(), CreateText(), OpenRead(), OpenText(), OpenWrite(), AppendText()
Класс File имеет практически такие же методы, но в статическом
исполнении
•
File.Delete(“c:\\myText.txt”);


Статический класс
Работа с путями
•

Комбинирование путей
•




GetInvalidPathChars, GetInvalidFileNameChars, IsPathRooted, HasExtension
Работа с временными папками
•

Combine, ChangeExtension
Проверки
•

GetPathRoot, GetDirectoryName, GetFullPath, GetFileName,
GetFileNameWithoutExtension, GetExtension
GetTempPath , GetTempFileName
Не изменяет сами объекты, т.е. не переименовывает и не перемещает
(исключение GetTempFileName - создаёт физически файл на диске)
Не проверяет наличие объектов физически
Проверяет валидность задания путей. Например проверяет допустимость
символов
Полезным может быть также статический класс Environment
Слушает сообщения об изменениях в файловой
системе и генерирует события
 Настройка:

• Path – папка за изменениями которой нужно следить
• Filter – задает фильтр объектов за которыми следить
• NotifyFilter – задает за какими изменениями следить
 (Attributes, CreationTime, DirectoryName, FileName, LastAccess,
LastWrite, Security, Size)
• Начало слежения – установка свойства
EnableRaisingEvents = true

Генерирует события
• 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
FileStream
поток из файла
SqlFileStream
MemoryStream
поток из памяти
NetworkStream
поток из сети
…
PipeStream
Поток данных из
именованных каналов
UnmanagedMemoryStream
поток неуправляемых данных
 CryptoStream
– предоставляет шифрование
потока
 BufferedStream – добавляет буферизацию
 GZipStream, DeflateStream – предоставляют
возможность сжатия потока
 BinaryReader/BinaryWriter,
StreamReader/StreamWriter –
предоставляют удобные способы
чтения/записи в поток
Классы обертки. Оборачивают конкретный поток
 Бинарный доступ к потоку
 Чтение/запись встроенных типов

• ReadXXX() / WriteXXX()
• XXX = Int32, Single, Double, …

«Подсмотреть» следующий символ
• PeekChar()

Кодировка по умолчанию UTF8
 Классы
обертки. Оборачивают конкретный
поток
 Текстовый доступ к потоку
 Чтение/запись строк
• ReadLine() – чтение строки
• ReadToEnd() – сразу весь файл
• Write() – запись строки
• WriteLine() – запись строки + символ новой строки
 Параметры
аналогичны функциям консоли
 System.Text.Encoding
 Определяет
преобразование
• char (Unicode) <=> byte []
GetEncoding() получает
кодировку по
 Encoding
• Имени: GetEncoding(“windows-1251”)
• Номеру: GetEncoding(1251)
 Использование:
• StreamReader sr = new StreamReader(stream,
Encoding.Unicode);
 TextReader/TextWriter
– базовые классы
• StreamReader/StreamWriter – из потока
• StringReader/StringWriter – из строки
 Стандартные
потоки
• Console.In – поток ввода
• Console.Out – поток вывода
• Console.Error – поток ошибок
Текстовый ввод-вывод
Download