- •Работа с файловой системой 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(int argc, char *argv[]);
Void main(int argc, char *argv[]) {
unsigned fattr;
_dos_getfileattr(argv[1], &fattr);
_dos_setfileattr(argv[1], fattr ^ _A_RDONLY);
}
Программа сначала считывает байт атрибутов, затем инвертирует соответствующий бит и устанавливает новое значение байта атрибутов.
3.8. Буферизация ввода/вывода
Ввод/вывод для дисков в операционной системе MS-DOS буферизован. Это означает, что данные не сразу записываются на диск, а накапливаются в специальном массиве (буфере). По мере заполнения буфер сбрасывается на диск. При чтении информация заполняет весь входной буфер, независимо от количества байтов, которые программа читает из файла. В дальнейшем, если программе потребуются данные, которые уже были считаны с диска и записаны во входной буфер, она получит данные непосредственно из этого буфера. Обращения к диску при этом не будет.
Буферизация сокращает затраты времени на ввод/вывод, особенно в тех случаях, когда программе периодически требуется одни и те же участки файлов. При копировании файлов буферизация сокращает время на перемещение головок от исходного файла к результирующему и обратно, причем эффект получается тем больше, чем больше размер используемого буфера.
Операционная система MS-DOS имеет несколько буферов. Их количество зависит от оператора BUFFERS, находящегося в файле CONFIG.SYS. Этот оператор позволяет определить от 2 до 99 буферов. Если файл CONFIG.SYS не содержит оператора BUFFERS, по умолчанию используются два буфера.
При увеличении количества буферов увеличивается вероятность того, что нужная часть файла уже считана и находится в оперативной памяти. Однако необходимо учитывать, что для хранения буферов расходуется основная оперативная память. Кроме того, с ростом количества буферов увеличивается время, необходимое операционной системе на анализ состояния буферов, что может привести к снижению производительности. Значительное снижение скорости работы наступает при количестве буферов порядка 50.
Обычно для машин класса AT с диском размером 20-40 мегабайтов рекомендуется использовать 32 буфера, однако для каждого конкретного случая может потребоваться подбор этого параметра для оптимизации производительности системы.
Если ваша программа интенсивно использует обращение к каталогам файловой системы, вы можете использовать утилиту MS-DOS FASTOPEN, которая запоминает в оперативной памяти расположение на диске файлов и каталогов, уменьшая интенсивность обращения к диску. Например, при использовании следующей команды в оперативной памяти будет храниться информация о расположении максимально о 100 файлах и каталогах:
FASTOPEN c:=100
В операционной системе MS-DOS версии 4.0 вы можете указать для утилиты FASTOPEN опцию /X. Эта опция вызывает размещение информации о файлах и каталогах в дополнительной (expanded) памяти. Для этой версии операционной системы вызов утилиты FASTOPEN лучше всего выполнять через оператор INSTALL файла CONFIG.SYS:
INSTALL=C:\DOS\FASTOPEN d: =(n,m) ... [/X]
В приведенной выше строке используются следующие обозначения:
d: |
обозначение диска; |
n |
количество файлов или каталогов, для которых необходимо запомнить расположение, может иметь значение от 1 до 999, по умолчанию используется 34; |
m |
количество буферов для фрагментированных файлов, может иметь значение от 1 до 999, по умолчанию используется 34; |
/X |
задает расположение буферов в дополнительной памяти. |
Еще один способ организовать буферизацию ввода/вывода для жестких дисков - использовать драйвер SMARTDRV.SYS. Этот драйвер позволяет создать для диска кэш-память в расширенной или дополнительной памяти. Например, следующая строка в файле CONFIG.SYS определяет дисковый кэш размером 530 килобайтов, размещенный в расширенной памяти:
device=c:\dos\smartdrv.sys 530
Кэш-память особенно эффективна при работе с базами данных, когда вам периодически требуется одна и та же информация. Если создать кэш-память достаточно большого размера, можно значительно сократить количество обращений к диску.
Если вы используете кэш-память для диска, не следует задавать оператор BUFFERS в файле CONFIG.SYS или пользоваться утилитой FASTOPEN, так как это приведет к многократной буферизации и вызовет излишние пересылки данных в оперативной памяти.
Буферизация данных имеет и свои недостатки. Если в результате аварии в питающей сети или по какой-то другой причине компьютер выключился, то информация, хранящаяся в буферах и не записанная на диск, будет потеряна.
При закрытии файла все буфера, связанные с ним, сбрасываются на диск. Если вам надо сбросить буфера, не закрывая файл, это можно сделать с помощью функции 68h прерывания INT 21h:
На входе: |
AH = 68h |
|
BX = файловый индекс открытого файла |
На выходе: |
AX = Код ошибки, если был установлен в 1 флаг переноса CF; 0, если операция выполнена успешно. |
Дополнительно обновляется дескриптор файла в каталоге, а именно поля времени, даты и размера файла.
Обратите также внимание на функцию расширенного открытия файлов 6Ch, входящую в состав MS-DOS версии 4.0. Эта функция позволяет при открытии файла отменить буферизацию.
Стандартные библиотеки трансляторов Microsoft QC 2.5 и C 6.0 содержат многочисленные функции, использующие собственный механизм буферизации при работе с файлами. Их часто называют функциями потокового ввода/вывода. Такую буферизацию не следует путать с буферизацией, выполняемой операционной системой. Имена всех этих функций начинаются на f - fopen(), fclose(), fprintf() и т.д.
Функции потокового ввода/вывода хорошо описаны во многих учебных пособиях по языку программирования Си, поэтому мы приведем лишь краткий обзор этих функций, делая акцент на особенностях их применения.
При использовании функций потокового ввода/вывода файлы открываются функцией fopen(), закрываются функцией fclose(). Эти функции не только открывают и закрывают файлы (получают и освобождают их файловый индекс), но и, соответственно, создают и уничтожают структуру типа FILE, описанную в файле stdio.h и связанную с данным файлом:
extern FILE {
char *_ptr; // положение текущего символа
