
- •Работа с файловой системой dos
- •Получение справочной информации
- •Void far *drv_addr;
- •24.11Стандартные библиотеки трансляторов Microsoft qc 2.5 и Borland содержат несколько функций, облегчающих получение справочной информации о состоянии дисковой подсистемы.
- •Void _dos_getdrive(unsigned *drive);
- •Void _dos_setdrive(unsigned drive, unsigned *drivecount);
- •Void main(void);
- •Void main(void) {
- •Создание, удаление и переименование каталогов
- •Void main(void);
- •Void main(void) {
- •Void main(void);
- •Void main(void) {
- •If(!mkdir(test_dir)) {
- •Int rename(char *oldname, char *newname);
- •Поиск в каталогах
- •Int _dos_findfirst(char *pattern, struct find_t *found, unsigned attr);
- •Int _dos_findnext(struct find_t *found);
- •Void print_info(struct find_t *pfind) {
- •Работа с файлами
- •Int creat(char *filename, int mode);
- •Int open(char *filename,
- •Int oflag [, int pmode]);
- •Int close(int handle);
- •3.5. Чтение/запись файлов
- •Int write(int handle, void *buffer, unsigned count);
- •Int read(int handle, void *buffer, unsigned count);
- •Void main(int, char *[]);
- •Void main(int argc, char *argv[]) {
- •Int source, taget, I;
- •Int eof(int handle);
- •3.6. Позиционирование
- •Void main(void);
- •Void main(void) {
- •Int handle;
- •3.7. Изменение атрибутов, времени и даты файлов
- •Void main(int argc, char *argv[]);
- •Void main(int argc, char *argv[]) {
- •3.8. Буферизация ввода/вывода
- •Int _cnt; // количество оставшихся байтов
- •Int fclose(file *stream);
- •Int fileno(file *stream);
- •Int fseek(file *stream, long offset, int origin);
- •Int fgetpos(file *stream, fpos_t *pos);
- •Int fsetpos(file *stream, fpos_t *pos);
- •Int fputc(int c, file *stream);
- •Int fgetc(file *stream);
- •Int fputs(char *string, file *stream);
- •Int fgets(char *string, int n, file *stream);
- •Int fprintf(file *stream, char *format [,arg]...);
- •Int fscanf(file *stream, char *format [,arg]...);
- •Void setbuf(file *stream, char *buffer);
- •Int setvbuf(file *stream, char *buffer, int mode,
- •Int fflush(file *stream);
- •Void filecpy(file *stream_from, file *stream_to);
- •Void main(int argc, char *argv[]) {
- •Void filecpy(file *stream_from, file *stream_to) {
- •3.9. Другие функции для работы с файлами
- •Int setmode(int handle, int mode);
- •Void rewind(file *stream);
- •Int dup(int handle);
- •Int dup2(int handle1, int handle2);
- •3.10. Таблица открытых файлов
Void main(void);
Void main(void) {
Int handle;
long position, length;
char buffer[2], fname[80];
// Запрашиваем имя файла, с которым будем работать
printf("Введите имя файла: ");
gets(fname);
// Открываем файл
handle = open(fname, O_BINARY | O_RDONLY);
// Если такого файла нет, выводим сообщение об ошибке
// и завершаем работу программы
if(handle == -1) {
printf("\nНет такого файла!");
exit(-1);
}
// Определяем и выводим на экран размер файла в байтах
length = filelength(handle);
printf("\nДлина файла %s составляет %ld байтов\n", fname, length);
// Запрашиваем позицию для чтения и отображения байта
do {
printf("Введите позицию: ");
scanf("%ld", &position);
} while(position > length);
// Устанавливаем заданную позицию
lseek(handle, position, SEEK_SET);
// Читаем один байт в буфер, начиная с установленной
// позиции
if(read(handle, buffer, 1) == -1) {
// Для вывода сообщения об ошибке используем функцию perror(),
// которая добавляет к сообщению, заданному в параметре,
// расшифрованное системное сообщение об ошибке.
// Код ошибки функция perror() берет из переменной errno.
perror("Ошибка при чтении");
exit(-1);
}
// Выводим считанный байт на экран
printf( "Смещение: %ld; байт: %02.2x ('%c')\n",
position, (unsigned char)*buffer, *buffer);
// Определяем текущую позицию и выводим ее
// на экран
position = tell(handle);
printf("\nТекущая позиция в файле: %ld\n", position);
// Закрываем файл
close(handle);
}
3.7. Изменение атрибутов, времени и даты файлов
Напомним: атрибуты файла, время и дата его последней модификации, а также размер файла хранятся в дескрипторе файла. Дескриптор файла находится в каталоге.
Операционная система предоставляет вам все необходимые средства для изменения всех полей дескриптора файла, кроме номера начального кластера. Для изменения этого номера вам придется работать с каталогом через таблицу размещения файлов FAT. Вам придется сначала считать каталог по кластерам с помощью прерывания INT 25h, модифицировать нужные поля и записать каталог обратно на диск при помощи прерывания INT 26h.
Для работы с полем атрибутов файла предназначена функция 43h прерывания INT 21h:
На входе: |
AH = 43h |
|
AL = выполняемая операция: 00h чтение атрибутов файла 01h установка новых атрибутов файла |
|
CX = новые атрибуты файла, если AL = 01h: Биты: 5 - бит архивации 4 - каталог 3 - метка диска 2 - системный файл 1 - скрытый файл 0 - только читаемый файл |
|
DS:DX = путь файла в формате ASCIIZ |
На выходе: |
AX = Код ошибки, если был установлен в 1 флаг переноса CF |
|
CX = Если не было ошибки, этот регистр содержит атрибуты файла |
При изменении атрибутов файла допустимо указывать комбинации битов в регистре CX.
Если ваша программа работает в сети, она должна иметь соответствующие права доступа к каталогу, содержащему файл, для которого программа собирается изменять байт атрибутов.
Для работы с полями времени и даты последней модификации файла предназначена функция 57h прерывания INT 21h:
На входе: |
AH = 57h |
|
AL = выполняемая операция: 00h чтение даты и времени 01h установка даты и времени |
|
BX = файловый индекс открытого файла |
|
CX = время |
|
DX = дата |
На выходе: |
AX = Код ошибки, если был установлен в 1 флаг переноса CF |
|
CX = Если не было ошибки, этот регистр содержит время последнего изменения файла |
|
DX = Если не было ошибки, этот регистр содержит дату последнего изменения файла |
Для того, чтобы изменить время или дату последней модификации файла с помощью этой функции, файл предварительно должен быть открыт. Формат времени и даты для этой функции такой же, как и используемый в дескрипторе каталога. Приведем эти форматы еще раз для удобства.
Формат поля времени:
15 11 10 5 4 0
++
¦ Часы (0...23) ¦ Минуты (0...59) ¦ Секунды/2 (0...29) ¦
++
Формат поля даты:
15 9 8 5 4 0
++
¦ Год (0...119) ¦ Месяц (1...12) ¦ День (1...31) ¦
++
Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат функции для чтения и изменения атрибутов файлов и времени/даты их последней модификации.
Для определения атрибутов файла можно использовать функцию _dos_getfileattr():
unsigned _dos_getfileattr(char *path, unsigned *attrib);
Эта функция получает атрибуты файла, заданного первым аргументом, и записывает байт атрибутов в младший байт по адресу, указанному вторым параметром.
В случае успешного завершения функция возвращает 0, в противном случае она возвращает код ошибки, полученный от операционной системы и устанавливает глобальную переменную errno в значение ENOENT, что означает отсутствие указанного в параметре path файла.
Для изменения атрибутов файла можно использовать функцию _dos_setfileattr():
unsigned _dos_setfileattr(char *path, unsigned attrib);
Параметр attrib может принимать следующие значения:
_A_ARCH |
установка бита архивации |
_A_HIDDEN |
файл скрытый |
_A_NORMAL |
обычный файл |
_A_RDONLY |
только читаемый файл |
_A_SUBDIR |
каталог |
_A_SYSTEM |
системный файл |
_A_VOLID |
метка диска |
Для определения времени последней модификации файла можно использовать функцию _dos_getftime():
unsigned _dos_getftime(int handle, unsigned *date, unsigned *time);
Перед использованием этой функции программа должна открыть файл. Дата и время записываются по адресу, указываемому, соответственно, вторым и третьим параметрами.
Если вам надо изменить время или дату последней модификации файла, используйте функцию _dos_setftime():
unsigned _dos_setftime(int handle, unsigned date, unsigned time);
Параметры этой функции аналогичны используемым в функции _dos_getftime(), за исключением того, что в качестве второго и третьего параметра применяются не указатели, а непосредственные значения даты и времени.
Приведем программу, изменяющую при запуске значение бита файла атрибутов "Только читаемый" для файла, имя которого передается программе в качестве параметра:
#include <dos.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>