- •Тема 11. Модульное программирование: файлы и потоки
- •Описание и внутреннее представление файлов
- •Текстовые и бинарные файлы
- •Базовые операции над файлами
- •Позиционирование в файле
- •Библиотечные функции работы с файлами
- •Понятие потока
- •Назначение классов потокового ввода-вывода
- •Функция pthread_join
- •Функция pthread_exit
- •Список использованной литературы:
- •Список контрольных вопросов
Базовые операции над файлами
Большинство современных ОС рассматривают файл как неструктурированную последовательность байт переменной длины. В стандарте POSIX над файлом определены следующие операции:
int open(char * fname, int flags, mode_t mode)
Эта операция “открывает” файл, устанавливая соединение между программой и файлом. При этом программа получает дескриптор файла - целое число, идентифицирующее данное соединение. Фактически это индекс в системной таблице открытых файлов для данной задачи. Все остальные операции используют этот индекс для ссылки на файл.
Параметр char * fname задает имя файла. int flags - это битовая маска, определяющая режим открытия файла. Файл может быть открыт только на чтение, только на запись и на чтение и запись; кроме того, можно открывать существующий файл, а можно пытаться создать новый файл нулевой длины. Необязательный третий параметр mode используется только при создании файла и задает атрибуты этого файла.
off_t lseek(int handle, off_t offset, int whence)
Эта операция перемещает указатель чтения/записи в файле. Параметр offset задает количество байт, на которое нужно сместить указатель, а параметр whence - откуда отсчитывать смещение. Предполагается, что смещение можно отсчитывать от начала файла(SEEK_SET), от его конца (SEEK_END) и от текущего положения указателя (SEEK_CUR). Операция возвращает положение указателя, отсчитываемое от начала файла. Таким образом, вызов lseek (handle, 0, SEEK_CUR) возвратит текущее положение указателя, не передвигая его.
int read(int handle, char * where, size_t how_much)
Операция чтения из файла. Указатель where задает буфер, куда нужно поместить прочитанные данные; третий параметр указывает, сколько данных надо считать. Система считывает требуемое число байт из файла, начиная с указателя чтения/записи в этом файле, и перемещает указатель к концу считанной последовательности. Если файл кончился раньше, считывается столько данных, сколько оставалось до его конца. Операция возвращает количество считанных байт. Если файл открывался только для записи, вызов read возвратит ошибку.
int ioctl (int handle, int cmd, ...); int fcntl (int handle, int cmd, ...)
Дополнительные операции над файлом. Первоначально, по-видимому, предполагалось, что ioctl - это операции над самим файлом, а fcntl - это операции над дескриптором открытого файла, но потом историческое развитие несколько перемешало функции этих системных вызовов. Стандарт POSIX определяет некоторые операции как над дескриптором, например дублирование (в результате этой операции мы получаем два дескриптора, связанных с одним и тем же файлом), так и над самим файлом, например, операцию truncate - обрезать файл до заданной длины. В большинстве версий Unix операцию truncate можно использовать и для вырезания данных из середины файла. При считывании данных из такой вырезанной области считываются нули, а сама эта область не занимает физического места на диске.
Важной операцией является блокировка участков файла. Стандарт POSIX предлагает для этой цели библиотечную функцию, но в системах семейства Unix эта функция реализована через вызов fcntl.
caddr_t mmap (caddr_t addr, size_t len, int prot, int flags, int handle, off_t offset)
Отображение участка файла в виртуальное адресное пространство процесса. Параметр prot задает права доступа к отображенному участку: на чтение, запись и исполнение. Отображение может происходить на заданный виртуальный адрес, или же система может выбирать адрес для отображения сама.
Еще две операции выполняются уже не над файлом, а над его именем: это операции переименования и удаления файла. В некоторых системах, например в системах семейства Unix, файл может иметь несколько имен, и существует только системный вызов для удаления имени. Файл удаляется при удалении последнего имени.
Видно, что набор операций над файлом в этом стандарте очень похож на набор операций над внешним устройством. И то и другое рассматривается как неструктурированный поток байт.
