В System.IO определено четыре класса для манипуляции с файлами и каталогами — File, FileInfo, Directory, DirectoryInfo. Классы Directory и File используются для создания, удаления, копирования и перемещения каталогов и файлов соответственно. Классы DirectoryInfo и FileInfo также используется для манипуляции с каталогами и файлами, но предлагают свою функциональность в виде методов уровня экземпляра — они должны размещаться в памяти с помощью ключевого слова new.
DirectoryInfo
- Create(), CreateSubdirectory() — создает каталог или дерево каталогов по заданному имени;
- Delete() — удаляет каталог вместе со всем содержим. Обратите внимание, в отличие от некоторых системных функций, удаляющих только пустой каталог, этот метод удаляет непустой каталог, что очень удобно — не нужно извлекать обход дерева каталогов.
- GetDirectory() — возвращает в себе массив объектов DirectoryInfo, представляющий собой все подкаталоги заданного (текущего) каталога;
- GetFiles() — извлекает массив объектов FileInfo, представляющий собой все файлы из текущего каталога;
- CopyTo() — копирует каталог со всем содержим;
- MoveTo() — перемещает весь каталог (с файлами и подкаталогами);
- Parent — содержит родительский каталог;
- Root — содержит корневой каталог.
Чтобы начать работу с DirectoryInfo, нужно создать новый объект этого типа, указав каталог, с которым вы будете работать:
Работа с файловой системой (6 класс)
DirectoryInfo d = new DirectoryInfo («C:Files»);
Классы Directory и DriveInfo
Члены этого класса обычно возвращают строковые данные, а не типизированные объекты типов FilesInfo/DirectorInfo — в этом основная разница этими двумя классами.
Рассмотри пример (выведем список дисков вашего компьютера):
Console.WriteLine(«Ваши диски:»); string[] drives = Directory.GetLogicalDrives(); foreach (string s in drives) Console.WriteLine(«», s);
Метод GetLogicalDrivers() возращает массив строк, а не массив объектов DirectoryInfo. Также метод вызывается без предварительного создания объекта оператором new. Данный метод сообщает буквы логических дисков, при этом невозможно понять, где и какой диск.
Если нужно получить больше информации о дисках, нужно использовать тип DriveInfo:
using System; using System.IO; namespace MyDriveInfo < class Program < static void Main (string[] args) < //Изменяем кодировку консоли для вывода текста Console.OutputEncoding = Encoding.GetEncoding(866); Console.WriteLine(«Ваши диски:»); string[] drives = Directory.GetLogicalDrives(); foreach (string s in drives) Console.WriteLine(«», s); DriveInfo[] drvs = DriveInfo.GetDrives(); foreach (DriveInfo d in drvs) < Console.WriteLine(«Диск: Тип «, d.Name, d.DriveType); if (d.IsReady) < Console.WriteLine(«Свободно: «, d.TotalFreeSpace); Console.WriteLine(«Файловая система: «, d.DriveFormat); Console.WriteLine(«Метка: «, d.VolumeLabel); Console.WriteLine(); > > Console.ReadeLine(); > > >
FileInfo
Текстовые файлы в с++ | программа с использованием файлов
Класс FileInfo используется для манипуляции с файлами.Рассмотрим его основные члены(методы):
Create()
Создает новый файл и возвращает объект FileStream, который используется для взаимодействия с созданным файлом.
CreateText()
Создает объект StreamWriter, который используется для создания текстового файла.
CopyTo()
Копирует существующий файл в другой файл.
AppendText()
Создает объект StreamWriter для добавления текста в файл.
Delete()
Удаляет файл, связанный с экземпляром FileInfo
Directory
Используется для получения экземпляра родительского каталога
DirectoryName
Содержит полный путь к родительскому каталогу
Length
Получает размер текущего файла или каталога.
MoveTo()
Используется для перемещения файла.
Name
Содержит имя файла.
Open()
Открывает файл с различными разрешениями чтения/записи.
OpenRead()
Создает доступный только для чтения объект FileStream.
OpenText()
Создает объект StreamReader для чтения информации из текстового файла.
OpenWrite()
Создает объект FileStream, доступный только для записи
Примеры использования класса FileInfo:
Использование метода Create():
Тут создаётся поток FileStream, позволяющий производить манипуляции с содержимым файла, например, читать из него данные, записывать в него данные.
File
Тип File поддерживает несколько полезных методов, которые пригодятся при работе с текстовыми файлами. Например, метод ReadAllLines() позволяет открыть указанный файл и прочитать из него все строки — в результате будет возвращен массив строк. После того, как все данные из файла прочитаны, файл будет закрыт.
Аналогично, метод ReadAllBytes() читает все байты из файла, возвращает массив байтов и закрывает файл.
Метод ReadAllText() читает все содержимое текстового файла в одну строку и возвращает её. Как обычно, файл после чтения будет закрыт.
Существует и аналогичные методы записи WriteAllBytes(), WriteAllLines() и WriteAlltext(), которые записывают в файл, соответственно, массив байтов, массив строк и строку. После записи файл закрывается. Рассмотрим пример:
Stream
В абстрактном классе System.IO.Stream определен набор членов, которые обеспечивают поддержку синхронного и асинхронного взаимодействия с хранилищем (например, файлом или областью памяти). Члены абстрактного класса:
CanRead, CarWrite, CanSeek
Определяют, поддерживает ли поток чтение, запись и поиск.
Close()
Метод закрывает поток и освобождает все ресурсы.
Flush()
Метод обновляет лежащий в основе источник данных. Напимер, позволяет перечитать источник.
Length
Возвращает длину потока в байтах.
Position
Определяет текущую позицию в потоке.
Read(), ReadByte()
Читает последовательность байт или один байт соответственно из текущего потока и перемещает позицию потока на количество прочитанных байтов.
Seek()
Устанавливает позицию в текущем потоке.
SetLength()
Устанавливает длину текущего потока.
Write(), WriteByte()
Записывает последовательность байтов или одиночный байт в текущий поток и перемещает текущую позицию на количество записанных байтов.
FileStream
Класс FileStream предоставляет реализацию абстрактного члена Stream для потоковой работы с файлами. Это элементарный поток, и он может записывать или читать только один байт или массив байтов.
Классы StreamWriter и StreamReader
Данные классы удобно использовать во всех случаях, когда нужно читать или записывать символьные данные. Оба типа работают по умолчанию с символами Unicode, но кодировку можно изменить предоставлением правильно сконфигурированной ссылки на объект System.Text.Encoding. Пример записи в файл с использованием StreamWriter:
using (StreamWriter writer = File.CreateText(«friends.txt»))
Пример чтения информации из текстового файла с помощью StreamReader:
using (StreamReader reader1 = File.OpenText(«friends.txt»)) < string s = null; while ((s = reader1.ReadLine()) != null) < Console.WriteLine(s); >>
Классы BinaryWriter и BinaryReader
Для работы с двоичными (не текстовыми) данными используются классы BinaryWriter и BinaryReader. Оба эти класса унаследованы от System.Object и позволяют читать и записывать данные в потоки в двоичном формате. Для записи у BinaryWriter используется метод Write(), а для чтения — метод Read() у BinaryReader. Метод Close (закрыть поток) есть у обоих классов.
Метод Flush() у BinaryWriter позволяет сбросить буфер двоичного потока на носитель. Пример использования:
Источник: it-black.ru
Операции над файлами
Операционная система должна предоставить в распоряжение пользователя набор операций для работы с файлами, реализованных через системные вызовы. Чаше всего при работе с файлом пользователь выполняет не одну, а несколько операций. Во-первых, нужно найти данные файла и его атрибуты по символьному имени, во-вторых, считать необходимые атрибуты файла в отведенную область оперативной памяти и проанализировать права пользователя на выполнение требуемой операции. Затем следует выполнить операцию, после чего освободить занимаемую данными файла область памяти. Рассмотрим в качестве примера основные файловые операции ОС Unix |Таненбаум, 2002]:
• Создание файла, не содержащего данных. Смысл данного вызова — объявить, что файл существует, и присвоить ему ряд атрибутов. При этом выделяется место для файла на диске и вносится запись в каталог.
• Удаление файла и освобождение занимаемого им дискового пространства.
• Открытие файла. Перед использованием файла процесс должен его открыть. Цель данного системного вызова — разрешить системе проанализировать атрибуты файла и проверить права доступа к нему, а также считать в оперативную память список адресов блоков файла для быстрого доступа к его данным. Открытие файла является процедурой создания дескриптора или управляющего блока файла.
Дескриптор (описатель) файла хранит всю информацию о нем. Иногда, в соответствии с парадигмой, принятой в языках программирования, под дескриптором понимается альтернативное имя файла или указатель на описание файла в таблице открытых файлов, используемый при последующей работе с файлом. Например, на языке Си операция открытия файла fd=open (pathname, flags,modes); возвращает дескриптор fd, который может быть задействован при выполнении операций чтения (read (fd, buffer, count);) или записи.
• Закрытие файла. Если работа с файлом завершена, его атрибуты и адреса блоков на диске больше не нужны. В этом случае файл нужно закрыть, чтобы освободить место во внутренних таблицах файловой системы.
• Позиционирование. Дает возможность специфицировать место внутри файла, откуда будет производиться считывание (или запись) данных, то есть задать текущую позицию.
• Чтение данных из файла. Обычно это делается с текущей позиции. Пользователь должен задать объем считываемых данных и предоставить для них буфер в оперативной памяти.
• Запись данных в файл с текущей позиции. Если текущая позиция находится в конце файла, его размер увеличивается, в противном случае запись осуществляется на место имеющихся данных, которые, таким образом, теряются.
Есть и другие операции, например переименование файла, получение атрибутов файла и т. д.
Существует два способа выполнить последовательность действий над файлами [Олифер, 2001].
В первом случае для каждой операции выполняются как универсальные, так и уникальные действия (схема stateless). Например, последовательность операций может быть такой: open, read 1, close. open, read2, close. open, rcad3, close.
Альтернативный способ — это когда универсальные действия выполняются в начале и в конце последовательности операций, а для каждой промежуточной операции выполняются только уникальные действия. В этом случае последовательность вышеприведенных операций будет вы- глядеть так: open, read 1. read2. read3, close.
Большинство ОС использует второй способ, более экономичный и быстрый. Первый способ более устойчив к сбоям, поскольку результаты каждой операции становятся независимыми от результатов предыдущей операции; поэтому он иногда применяется в распределенных файловых системах (например, Sun NFS).
Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:
Источник: studopedia.ru
Операции над файлами
Одной из главных функций ОС является управление всеми устройствами ввода-вывода компьютера. ОС должна передавать устройствам команды, перехватывать прерывания и обрабатывать ошибки; она также должна обеспечивать интерфейс между устройствами и остальной частью системы. В целях развития интерфейс должен быть одинаковым для всех типов устройств (независимость от устройств). Физическая организация устройств ввода-вывода Устройства ввода-вывода делятся на два типа: блок-ориентированные устройства и байт-ориентированные устройства. Блок-ориентированные устройства хранят информацию в блоках фиксированного размера, каждый из которых имеет свой собственный адрес. Самое распространенное блок-ориентированное устройство — диск. Байт-ориентированные устройства не адресуемы и не позволяют производить операцию поиска, они генерируют или потребляют последовательность байтов. Примерами являются терминалы, строчные принтеры, сетевые адаптеры. Однако некоторые внешние устройства не относятся ни к одному классу, например, часы, которые, с одной стороны, не адресуемы, а с другой стороны, не порождают потока байтов. Это устройство только выдает сигнал прерывания в некоторые моменты времени. Внешнее устройство обычно состоит из механического и электронного компонента. Электронный компонент называется контроллером устройства или адаптером. Механический компонент представляет собственно устройство. Некоторые контроллеры могут управлять несколькими устройствами. Если интерфейс между контроллером и устройством стандартизован, то независимые производители могут выпускать совместимые как контроллеры, так и устройства. Операционная система обычно имеет дело не с устройством, а с контроллером. Контроллер, как правило, выполняет простые функции, например, преобразует поток бит в блоки, состоящие из байт, и осуществляют контроль и исправление ошибок. Каждый контроллер имеет несколько регистров, которые используются для взаимодействия с центральным процессором. В некоторых компьютерах эти регистры являются частью физического адресного пространства. В таких компьютерах нет специальных операций ввода-вывода. В других компьютерах адреса регистров ввода-вывода, называемых часто портами, образуют собственное адресное пространство за счет введения специальных операций ввода-вывода. ОС выполняет ввод-вывод, записывая команды в регистры контроллера. Например, контроллер гибкого диска IBM PC принимает 15 команд, таких как READ, WRITE, SEEK, FORMAT и т.д. Когда команда принята, процессор оставляет контроллер и занимается другой работой. При завершении команды контроллер организует прерывание для того, чтобы передать управление процессором операционной системе, которая должна проверить результаты операции. Процессор получает результаты и статус устройства, читая информацию из регистров контроллера. Организация программного обеспечения ввода-вывода Основная идея: разбиение его на несколько уровней, причем нижние уровни обеспечивают экранирование особенностей аппаратуры от верхних, а те, в свою очередь, обеспечивают удобный интерфейс для пользователей. Ключевым принципом является независимость от устройств. Очень близкой к идее независимости от устройств является идея единообразного именования, то есть для именования устройств должны быть приняты единые правила. Рис. 2.30. Многоуровневая организация подсистемы ввода-вывода Другим важным вопросом для программного обеспечения ввода-вывода является обработка ошибок. Ошибки следует обрабатывать как можно ближе к аппаратуре. Если контроллер обнаруживает ошибку чтения, то он должен попытаться ее скорректировать. Если же это ему не удается, то исправлением ошибок должен заняться драйвер устройства. Многие ошибки могут исчезать при повторных попытках выполнения операций ввода-вывода. И только если нижний уровень не может справиться с ошибкой, он сообщает об ошибке верхнему уровню. Еще один ключевой вопрос — это использование блокирующих (синхронных) и неблокирующих (асинхронных) передач. Большинство операций физического ввода-вывода выполняется асинхронно. Пользовательские программы намного легче писать, если операции ввода-вывода блокирующие — после команды READ программа автоматически приостанавливается до тех пор, пока данные не попадут в буфер программы. ОС выполняет операции ввода-вывода асинхронно, но представляет их для пользовательских программ в синхронной форме. Последняя проблема состоит в том, что одни устройства являются разделяемыми, а другие — выделенными. Диски — это разделяемые устройства, т.к. позволяют одновременный доступ нескольких пользователей. Принтеры — это выделенные устройства, потому что нельзя смешивать строчки, печатаемые различными пользователями. Наличие выделенных устройств создает для операционной системы некоторые проблемы. Для решения поставленных проблем целесообразно разделить ПО ввода-вывода на четыре слоя (рис. 2.30):
- Обработка прерываний,
- Драйверы устройств,
- Независимый от устройств слой операционной системы,
- Пользовательский слой программного обеспечения.
Обработка прерываний Прерывания должны быть скрыты как можно глубже в недрах операционной системы, чтобы как можно меньшая часть ОС имела с ними дело. Наилучший способ состоит в разрешении процессу, инициировавшему операцию ввода-вывода, блокировать себя до завершения операции и наступления прерывания. Процесс может блокировать себя, используя, например, вызов DOWN для семафора, или вызов WAIT для переменной условия, или вызов RECEIVE для ожидания сообщения. При наступлении прерывания процедура обработки прерывания выполняет разблокирование процесса, инициировавшего операцию ввода-вывода, используя вызовы UP, SIGNAL или посылая процессу сообщение. В любом случае эффект от прерывания будет в том, что ранее заблок-ный процесс теперь продолжит свое выполнение. Драйверы устройств Весь зависимый от устройства код помещается в драйвер устройства. Каждый драйвер управляет устройствами одного типа или, может быть, одного класса. В операционной системе только драйвер устройства знает о конкретных особенностях какого-либо устройства. Например, только драйвер диска имеет дело с дорожками, секторами, цилиндрами, временем установления головки и другими факторами, обеспечивающими правильную работу диска. Драйвер устройства принимает запрос от устройств программного слоя и решает, как его выполнить. Типичным запросом является чтение n блоков данных. Если драйвер был свободен во время поступления запроса, то он начинает выполнять запрос немедленно. Если же он был занят обслуживанием другого запроса, то вновь поступивший запрос присоединяется к очереди уже имеющихся запросов, и он будет выполнен, когда наступит его очередь. Первый шаг в реализации запроса ввода-вывода, например, для диска, состоит в преобразовании его из абстрактной формы в конкретную. Для дискового драйвера это означает преобразование номеров блоков в номера цилиндров, головок, секторов, проверку, работает ли мотор, находится ли головка над нужным цилиндром. Короче говоря, он должен решить, какие операции контроллера нужно выполнить и в какой последовательности. После передачи команды контроллеру драйвер должен решить, блокировать ли себя до окончания заданной операции или нет. Если операция занимает значительное время, как при печати некоторого блока данных, то драйвер блокируется до тех пор, пока операция не завершится, и обработчик прерывания не разблокирует его. Если команда ввода-вывода выполняется быстро (например, прокрутка экрана), то драйвер ожидает ее завершения без блокирования. Независимый от устройств слой операционной системы Большая часть программного обеспечения ввода-вывода является независимой от устройств. Точная граница между драйверами и независимыми от устройств программами определяется системой, так как некоторые функции, которые могли бы быть реализованы независимым способом, в действительности выполнены в виде драйверов для повышения эффективности или по другим причинам. Типичными функциями для независимого от устройств слоя являются:
- обеспечение общего интерфейса к драйверам устройств,
- именование устройств,
- защита устройств,
- обеспечение независимого размера блока,
- буферизация,
- распределение памяти на блок-ориентированных устройствах,
- распределение и освобождение выделенных устройств,
- уведомление об ошибках.
Пользовательский слой программного обеспечения Хотя большая часть программного обеспечения ввода-вывода находится внутри ОС, некоторая его часть содержится в библиотеках, связываемых с пользовательскими программами. Системные вызовы, включающие вызовы ввода-вывода, обычно делаются библиотечными процедурами. В частности, форматирование ввода или вывода выполняется библиотечными процедурами. Примером может служить функция printf языка С, которая принимает строку формата и, возможно, некоторые переменные в качестве входной информации, затем строит строку символов ASCII и делает вызов write для вывода этой строки. Стандартная библиотека ввода-вывода содержит большое число процедур, которые выполняют ввод-вывод и работают как часть пользовательской программы. Другой категорией программного обеспечения ввода-вывода является подсистема спулинга (spooling). Спулинг — это способ работы с выделенными устройствами в мультипрограммной системе. Рассмотрим типичное устройство, требующее спулинга — строчный принтер. Хотя технически легко позволить каждому пользовательскому процессу открыть специальный файл, связанный с принтером, такой способ опасен из-за того, что пользовательский процесс может монополизировать принтер на произвольное время. Вместо этого создается специальный процесс — монитор, который получает исключительные права на использование этого устройства. Также создается специальный каталог, называемый каталогом спулинга. Для того, чтобы напечатать файл, пользовательский процесс помещает выводимую информацию в этот файл и помещает его в каталог спулинга. Процесс-монитор по очереди распечатывает все файлы, содержащиеся в каталоге спулинга.
- Проектирование программ. Этапы разработки ПО. Жизненный цикл программ.
- Разработка общего алгоритма программы.
- Описание алгоритма каждого блока общего алгоритма.
- Выбор языка программирования и средств реализации (хранение данных, выбор формата данных и т.д., и т.п.).
- Написание кода, задание начальных данных.
- Отладка программы.
- Тестирование. (Возвращение снова ко второму пункту и заново).
- Внедрение.
- Поддержка продукта. (Иногда это возвращение к более поздним или ранним пунктам).
Программирование – теоретическая и практическая деятельность, связанная с созданием программ. Решение задач на компьютере включает в себя следующие основные этапы, часть из которых осуществляется без участия компьютера.
- Постановка задачи:
- сбор информации о задаче;
- формулировка условия задачи;
- определение конечных целей решения задачи;
- определение формы выдачи результатов;
- описание данных (их типов, диапазонов величин, структуры и т. п.).
- Анализ и исследование задачи, модели:
- анализ существующих аналогов;
- анализ технических и программных средств;
- разработка математической модели;
- разработка структур данных.
- Разработка алгоритма:
- выбор метода проектирования алгоритма;
- выбор формы записи алгоритма (блок-схемы, псевдокод и др.);
- выбор тестов и метода тестирования;
- проектирование алгоритма.
- Программирование:
- выбор языка программирования;
- уточнение способов организации данных;
- запись алгоритма на выбранном языке программирования.
- Тестирование и отладка:
- синтаксическая отладка;
- отладка семантики и логической структуры;
- тестовые расчеты и анализ результатов тестирования;
- совершенствование программы.
- Анализ результатов решения задачи и уточнение в случае необходимости математической модели с повторным выполнением этапов 2-5.
- Сопровождение программы:
- доработка программы для решения конкретных задач;
- составление документации к решенной задаче, к математической модели, к алгоритму, к программе, к набору тестов, к использованию.
Анализ Различают 2 случая производства ПП: 1) ПП делается для конкретного заказчика. В этом случае нужно прикладную задачу превращать в программистскую. Нужно понять, как функционирует та среда, которую нужно автоматизировать (анализ бизнес-процессов). В результате появляется документация-спецификация требования, где указаны какие именно задачи д.б. решены и при каких условиях. Эту работу выполняет системный аналитик (аналитик бизнес-процессов). 2) ПП разрабатывается для рынка. Нужно проводить маркетинговые исследования и найти какого продукта на рынке нет. Это связано с большим риском. Цель – разработка спецификации требований. Проектирование Цель – определ общей структуры (архитектуры) ПП. Результат – спецификация ПП. работу выполняет сист программист. Реализация Написание программного кода. Реализация включает и разработку, и тестирование, и документацию. Сборка, тестирование, испытание Сборка всего, что сделано разными программистами. Тестирование всего программного комплекса. Отладка – поиск и устранение причин ошибок. Испытание – уточнение технических характеристик. В результате – гарантия работоспособности программы. Внедрение (выпуск) Внедрение – когда работают на одного заказчика. Включает постановку программы у заказчика, обучение заказчика, консультации, устранение ошибок и явных недостатков. Должно произойти отчуждение ПП – пользователь может работать с ПП без участия автора. Выпуск – когда ПП разрабатывается на рынок. Начинается с этапа бета-тестирования. Соотв. версия – бета-версия. Альфа-тестирование – тестирование людьми из той же организации, не участвовавших в разработке программ. Бета-тестирование – изготовление нескольких экземпляров ПП и отправка потенциальным заказчикам. Цель – еще раз проверить разработку ПП. Если на рынок выпускается принципиально новый ПП, то возможно несколько бета-тестирований. После бета-тестирование – выпуск коммерческой версии. Сопровождение Устранение замеченных в ходе эксплуатации ошибок. Внесение непринципиальных усовершенствований. Накопление предложений для разработки следующей версии.
Источник: studfile.net