- •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.6. Читання даних з файла
Для читання даних з файла служить функція ReadFile(), яка може використовуватися як для синхронного, так і асинхронного читання даних. Тепер розглянемо тільки синхронне читання даних з файла. У цьому випадку дані читаються з файла послідовно байт за байтом, і покажчик файла пересувається у міру читання даних на нову позицію. Асинхронне введення-виведення даних буде розглянуто пізніше.
Тепер детальніше розглянемо функцію ReadFile(), яка має наступний прототип:
BOOL ReadFile(
HANDLE hFile, // дескриптор файла
LPVOID lpBuffer, // покажчик на буфер даних
DWORD nNumberOfBytesToRead, // число байтів, які будуть читатися
LPDWORD lpNumberOfBytesRead, // число зчитаних байтів
LPOVERLAPPED lpOverlapped ); // використовується при асинхронному записі
У разі успішного завершення функція повертає ненульове значення, інакше - false.
Параметр hFile повинен містити дескриптор файла, причому файл має бути відкритий в режимі читання.
Параметр lpBuffer повинен вказувати на область пам’яті, з якої читатимуться дані.
Параметр nNumberOfBytesToRead повинен містити число байтів, які передбачається читати з файла за допомогою виклику функції ReadFile().
Параметр lpNumberOfBytesRead повинен містити адресу пам’яті, в яку функція ReadFile() помістить число фактично зчитаних з файла байтів.
Через те, що ми не розглядатимемо асинхронне читання даних з файла, то параметр lpOverlapped встановлюватиметься в null.
Детально асинхронне введення-виведення даних буде розглянуте пізніше.
У лістингу 24.4 приведена програма, яка читає дані з файла, створеного програмою з лістингу 24.2, і виводить ці дані на консоль.
// Лістинг 24.4. Відкриття файла і читання з нього даних
#include "stdafx.h"
int main()
{
HANDLE hFile;
wchar_t lpszFileName[] = L"C:\\Users\\Shogun\\Documents\\demo_file.txt ";
// відкриваємо файл для читання
hFile = CreateFile(
lpszFileName, // ім'я файла
GENERIC_READ, // читання із файла
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;
}
// читаємо дані із файла
for (;;) {
DWORD dwBytesRead;
int n;
// читаємо один запис
if (!ReadFile(
hFile, // дескриптор файла
&n, // адреса буфера, куди читаємо дані
sizeof(n), // число байтів, які читаємо
&dwBytesRead, // число прочитаних байтів
(LPOVERLAPPED)NULL // читання синхронне
))
{
std::cerr << "Read 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;
}
// перевіряємо на кінець файла
if (dwBytesRead == 0)
// якщо так, то виходимо із циклу
break;
else
// інакше виводимо запис на консоль
std::cout << n << ' ';
}
std::cout << std::endl;
// закриваємо дескриптор файла
CloseHandle(hFile);
std::cout << "The file is opened and read." << std::endl;
std::cin.get();
return 0;
}
У зв’язку з цією програмою відмітимо обробку кінця файла. Досягши кінця файла і запиті на читання запису функція ReadFile() повертає ненульове значення і при цьому встановлює значення числа прочитаних байтів в 0.
