Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lek13_14.doc
Скачиваний:
9
Добавлен:
13.07.2019
Размер:
695.3 Кб
Скачать

3. Позиционирование указателя файла.

С каждым файлом связана некая внутренняя системная переменная, которая указывает на то место в файле, с которого будут начинаться операции ввода/вывода. Эта переменная, доступ к которой напрямую программист получить не может, называется указателем файла. При открытии файла этот указатель обычно устанавливается перед самым первым символом файла. Для того, чтобы манипулировать этой переменной, существуют специальные функции. Одной из них является функция SetFilePointer(), синтаксис которой следующий:

DWORD SetFilePointer ( HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod )

Параметры:

hFile – хэндл файла.

lDistanceToMove – число байтов, на которое должен быть перемещен указатель файла. При положительном значении указатель перемещается в файле в прямом направлении, а при отрицательном – в обратном.

lpDistanceToMoveHighуказатель на старшие 32 бита 64-разрядного значения расстояния, на которое должно быть выполнено перемещение.

dwMoveMethod - отправная точка для перемещения указателя файла.

Возвращаемое значение. При успешном выполнении – 32 бита нового указателя файла, при ошибке – 0xFFFFFFFF.

Первый аргумент этой функции, hFile, очевиден. Это хэндл того файла, с которым работаем и в котором перемещаем указатель.

Второй аргумент, lDistanceToMove, является числом символов, на которое необходимо передвинуть указатель файла. Для установки нового значения указателя файла это число просто-напросто складывается со старым значением указателя файла, поэтому можно определять, в какую сторону будет смещён указатель. Если аргумент lDistanceToMove больше нуля, то указатель файла перемещается вперёд, то есть к концу файла. Отрицательное значение говорит о том, что указатель файла перемещается назад, то есть к началу файла.

Особенность. Тип этого аргумента - LONG, то есть используя только этот аргумент, невозможно переместить указатель файла больше, чем на 232 байта. А что нам делать, если нужно?

В этом случае нам на помощь приходит третий аргумент, через который можно передать указатель на буфер, содержащий старшие тридцать два разряда требуемого значения.

Таким образом, при определении нового значения указателя файла используется следующая формула:

НЗУ = СЗУ + lDistanceToMove + lpDistanceToMoveHigh,

где: НЗУ - это Новое Значение Указателя;

СЗУ - это Старое Значение Указателя.

Забегая вперед, отметим, что тип возвращаемого функцией значения -двойное слово. В этом двойном слове функция возвращает новое значение указателя файла. В том случае, когда тридцати двух разрядов для этого мало, старшие тридцать два разряда записываются по адресу lpDistanceToMoveHigh.

Четвертый аргумент, dwMoveMethod, определяет точку отсчёта для перемещения указателя файла. Возможные значения этого аргумента приведены в табл.4.

Таблица 4

Значения параметра dwMoveMethod функции SetFilePoint()

Метод

Значение

Назначение

FILE_BEGIN

0

Старое значение указателя игнорируется и считается равным нулю, то есть СЗУ в данном случае равно нулю.

FILE_CURRENT

1

Для вычислений используется текущее значение указателя.

FILE_END

2

Старое значение указателя принимается равным числу байтов в файле, то есть фактически указатель устанавливается в конец файла

В случае успешного завершения функция возвращает новое значение указателя. Но возможны ещё два случая.

Во-первых, функция может вернуть значение 0xFFFFFFFF, при этом слово, на которое указывает третий аргумент, может быть нулевым. Это будет означать, что при работе функции произошла ошибка.

Во-вторых, функция может вернуть значение 0xFFFFFFFF, при этом слово, на которое указывает третий аргумент, может быть не равно нулю. В этом случае для того, чтобы определить, произошла ли ошибка, необходимо вызвать функцию GetLastError(). Если эта функция вернёт значение, отличное от NO_ERROR, это будет являться сообщением об ошибке.

Установка конца файла

Обычно при закрытии файла система сама устанавливает конец файла и программисту не приходится об этом заботиться. Но иногда возникает необходимость увеличить или уменьшить размер файла. Для этих целей в Windows существует функция SetEndOfFile(), синтаксис которой следующий:

BOOL SetEndOfFile ( HANDLE hFile)

Параметры:

hFile – хэндл файла.

Возвращаемое значение. При успешном выполнении – TRUE, при ошибке - FALSE. В последнем случае для уточнения причины возникновения ошибки можно воспользоваться функцией GetLastError().

Конец файла устанавливается в том месте, на котором находится указатель файла. После того, как будет установлен конец файла, необходимо закрыть файл. Другими словами, если мы хотим изменить длину файла и сделать её равной, скажем, 65535, нам необходимо выполнить следующие действия:

HFILE hFile = CreateFile(...);

SetFilePointer(hFile, 65535, NULL, FILE_BEGIN);

SetEndOfFile(hFile);

CloseHandle(hFile);

4. Чтение данных из файла в буфер. Эта функция называется ReadFile(), которая считывает данные из файла с позиции, обозначенной указателем файла. После считывания данных указатель файла сдвигается на число считанных байт.

BOOL ReadFile (HANDLE hFipe, LPCVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, POVERLAPPED lpOverlapped)

Параметры:

hFipe – хэндл открытого файла.

lpBuffer – указатель на буфер, данные из которого будут записаны в файл.

nNumberOfBytesToRead – размер буфера для чтения.

lpNumberOfBytesRead – количества байт данных, действительно записанных в файл.

lpOverlapped – указатель на структуру OVERLAPPED

Возвращаемое значение. При успешном выполнении – TRUE, при ошибке - FALSE. В последнем случае для уточнения причины возникновения ошибки можно воспользоваться функцией GetLastError().

Замечание. Для того, чтобы функция могла бы выполниться успешно, файл, из которого необходимо производить чтение, должен быть открыт с флагом GENERIC_READ.

Первый аргумент этой функции, hFile, является хэндлом того файла, из которого производится чтение данных.

Второй аргумент, lpBuffer, указывает на буфер, в который производится чтение данных.

Третий аргумент, nNumberOfBytesToRead, определяет число байтов, которые нужно прочесть из файла. В буфер, на который указывает lpNumberOfBytesRead, будет записано число реально прочитанных байтов.

Последний аргумент, lpOverlapped, является указателем на структуру типа OVERLAPPED, но так как этот аргумент используется только для асинхронного ввода-вывода. Поэтому, при синхронном вводе необходимо передать функции через этот аргумент значение NULL.

Аргументы функции не определяют, из какого места файла нам необходимо производить чтение информации. Дело в том, что чтение производится с того места, на которое указывает указатель файла. Причём, к примеру, если файл только что открыт и мы производим чтение одного килобайта данных из начала файла, то после операции чтения указатель файла будет установлен на 1025-й байт. Если не сместить указатель, то после второй операции чтения он будет установлен на 2049-й байт, и так далее.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]