Чтение, запись, позиционирование в файле
Необходимо сразу отметить, что Win32 допускает два режима доступа к файлу – синхронный и асинхронный. Необходимость введения этих двух режимов в архитектуру Win32 вызвано тем, что файловый ввод-вывод относится к наиболее медленным операциям и способен значительно ухудшить впечатление от компьютера с хорошей центральной частью (процессором и материнской платой) и плохой дисковой подсистемой.
Поэтому разработчики Win32 уделяют много внимания моделированию файловых операций с использованием памяти компьютера. Это и упомянутые выше временные файлы и гибкая система кэширования вводимых и выводимых данных, а также файлы, отображенные в память, работу с которыми мы рассмотрим в конце данного раздела. Наше дальнейшее изложение будет посвящено организации синхронного ввода-вывода. Для обычных несложных приложений Win32 его вполне достаточно.
Установка текущей файловой позиции
Доступ к содержимому файла может быть произвольным (прямым) и последовательным. Как обычно, функции ввода-вывода работают с файловым указателем. Но необходимо иметь в виду, что файловый указатель связан только с описателем файла. Его значение равно текущему номеру позиции в файле, с которой будет производиться чтение-запись данных при очередном вызове функции ввода-вывода. В первый момент после открытия значение указателя равно 0, то есть он указывает на начало файла. Функции, производящие чтение-запись в файле, меняют значение файлового указателя на количество прочитанных или записанных байт.
При необходимости, а при организаций прямого доступа к файлу без этого не обойтись, значение файлового указателя можно изменять с помощью функции SetFilePointer:
DWORD SetFilePointer(HANDLE hFile, LONG IDistanceToMove. PLONG lpDistanceToMoveHigh. DWORD dwMoveMethod);
Параметры этой функции имеют размер двойного слова и следующее назначение:
cmp eax.O jz exit:если неуспех eld mov edi,p_start mov esi.p_start mov ecx.FileSize cycl: moval.Odh repne scasb cmp byte ptr [edi].0ah jne $-5 inc edi dec ecx jeexz exit:весь файл прочитан mov eax.edi sub eax.esi:в еах – длина строки для вывода на экран, а в esi – ее адрес ;вывести очередную строку call WriteConsoleA cmp eax,0 jz exit:если неуспех add esi,eax jmp cycl закрываем файлы exit::выход из приложения return: ¦
При небольшой модификации программы можно построчно выводить содержимое любого текстового файла. Для небольших файлов совсем необязательно отслеживать конец каждой строки – можно выводить из буфера сразу весь файл одним вызовом функции WriteConsoleA.