- •24.1. Іменування файлів у Windows
- •24.2. Створення і відкриття файлів
- •24.3. Закриття і видалення файлів
- •24.4. Запис даних у файл
- •24.5. Звільнення буферів файла
- •24.6. Читання даних з файла
- •24.7. Копіювання файла
- •24.8. Переміщення файла
- •24.9. Заміщення файла
- •24.10. Робота з покажчиком позиції файла
- •24.11. Визначення і зміна атрибутів файла
- •24.12. Визначення і зміна розмірів файла
- •24.13. Блокування файла
- •24.14. Отримання інформації про файл
24.13. Блокування файла
Часто декілька застосувань мають спільний доступ до одного і того ж файла. При цьому може буде потрібно, щоб застосування, яке змінює дані у файлі, мало до цього файла монопольний доступ. Для цього потрібно блокувати увесь файл або тільки його частину для доступу іншим застосуванням.
Для цих цілей використовується функція LockFile(), яка має наступний прототип:
BOOL LockFile(
HANDLE hFile, // дескриптор файла
DWORD dwFileOffsetLow, // молодша частина зміщення
DWORD dwFileOffsetHigh, // старша частина зміщення
DWORD nNumberOfBytesToLockLow, // молодша частина числа байтів
DWORD nNumberOfBytesTiLockHigh); // старша частина числа байтів
У разі успішного завершення функція повертає ненульове значення, інакше - false. Коротко опишемо призначення параметрів цієї функції.
Параметр hFile повинен містити дескриптор файла. Причому цей файл має бути відкритий в режимі запису або читання.
У параметрах dwFileOffsetLow і dwFileOffsetHigh мають бути встановлені відповідно молодша і старша частини зміщення від початку файла в байтах.
У параметрах nNumberOfBytesToLockLow і nNumberOfBytesTiLockHigh мають бути встановлені відповідно старша і молодша частині довжини області файла, яка блокується для монопольного доступу застосуванням.
Для відміни блокування області файла використовується функція UnlockFile(), яка має наступний прототип:
BOOL UnlockFile(
HANDLE hFile, // дескриптор файла
DWORD dwFileOffsetLow, // молодша частина зміщення
DWORD dwFileOffsetHigh, // старша частина зміщення
DWORD nNumberOfBytesToLockLow, // молодша частина числа байтів
DWORD nNumberOfBytesTiLockHigh); // старша частина числа байтів
У разі успішного завершення функція повертає ненульове значення, інакше - false. Всі параметри цієї функції аналогічні параметрам функції LockFiLe().
У лістингу 24.14 приведена програма, яка спочатку блокує доступ до файлf, а потім розблоковує його.
// Лістинг 24.14. Блокування і розблокування файла
#include "stdafx.h"
int main()
{
HANDLE hFile;
wchar_t lpszFileName[] = L"C:\\Users\\Shogun\\Documents\\demo_file.dat";
DWORD dwFileSize;
// відкриваємо файл для запису
hFile = CreateFile(
lpszFileName, // ім'я файла
GENERIC_WRITE, // запис у файл
0, // монопольний доступ до файла
NULL, // захисту немає
OPEN_EXISTING, // відкриваємо існуючий файл
FILE_ATTRIBUTE_NORMAL, // звичайний файл
NULL // шаблона немає
);
// перевіряємо на успішність відкриття
if (hFile == INVALID_HANDLE_VALUE)
{
std::cerr << "Create file failed." << std::endl
<< "The last error code: " << GetLastError() << std::endl;
std::cout << "Press any key to finish.";
std::cin.get();
return 0;
}
// визначаємо розмір файла
dwFileSize = GetFileSize(hFile, NULL);
if (dwFileSize == -1)
{
std::cerr << "Get file size failed." << std::endl
<< "The last error code: " << GetLastError() << std::endl;
CloseHandle(hFile);
std::cout << "Press any key to finish.";
std::cin.get();
return 0;
}
// блокуємо файл
if (!LockFile(hFile, 0, 0, dwFileSize, 0))
{
std::cerr << "Lock file failed." << std::endl
<< "The last error code: " << GetLastError() << std::endl;
CloseHandle(hFile);
std::cout << "Press any key to finish.";
std::cin.get();
return 0;
}
std::cout << "Now the file is locked." << std::endl
<< "Press any key to continue." << std::endl;
std::cin.get();
// розблоковуємо файл
if (!UnlockFile(hFile, 0, 0, dwFileSize, 0))
{
std::cerr << "Unlock file failed." << std::endl
<< "The last error code: " << GetLastError() << std::endl;
CloseHandle(hFile);
std::cout << "Press any key to finish.";
std::cin.get();
return 0;
}
std::cout << "Now the file is unlocked." << std::endl
<< "Press any key to continue." << std::endl;
std::cin.get();
// закриваємо дескриптор файла
CloseHandle(hFile);
return 0;
}
На завершення цього розділу зробимо декілька зауважень відносно використання функцій LockFile() і UnlockFile(). Передусім, відмітимо, що якщо застосування видає запит на блокування області файла, яка вже заблокована самим застосуванням, то виконання функції LockFile() завершиться невдачею. Крім того, блокування і розблокування файлів повинні співпадати по областях.
