- •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.14. Отримання інформації про файл
Щоб отримати інформацію про файл, можна використовувати функцію GetFileInformationByHandle(), яка має наступний прототип:
BOOL GetFileInformationByHandle(
HANDLE hFile, // дескриптор файла
LPBY_HANDLE_FILE_INFORMATION lpFilelnformation); // покажчик на інформацію
При успішному завершенні ця функція повертає ненульове значення, інакше - false.
У параметрі hFile цієї функції має бути встановлений дескриптор файла, інформацію про який потрібно отримати. Відмітимо, що цей файл може бути відкритий в будь-якому режимі доступу.
Параметр lpFileInformation повинен вказувати на структуру типу BY_HANDLE_FILE_INFORMATION, в яку функція запише інформацію про файл. Ця структура має наступний формат:
typedef struct _BY_HANDLE_FILE_INFORMATION {
DWORD dwFileAttributes; // атрибути файла
FILETIME ftCreationTime; // час створення файла
FILETIME ftLastAccessTime; // час останнього доступу до файла
FILETIME ftLastWriteTime; // час останнього запису у файл
DWORD dwVolumeSerialNumber; // серійний номер тому
DWORD nFileSizeHigh; // старша частина розміру файла
DWORD nFileSizeLow; // молодша частина розміру файла
DWORD nNumberOfLinks; // число посилань на файл
DWORD nFileIndexHigh; // старша частина індексу файла
DWORD nFilelndexLow; // молодша частина індексу файла
} BY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION;
У лістингу 24.15 приведена програма, яка отримує інформацію про файл і роздруковує її.
// Лістинг 24.15. Отримання інформації про файл
#include "stdafx.h"
int main()
{
HANDLE hFile;
wchar_t lpszFileName[] = L"C:\\Users\\Shogun\\Documents\\demo_file.dat";
BY_HANDLE_FILE_INFORMATION bhfi; // інформація про файл
// відкриваємо файл для читання
hFile = CreateFile(
lpszFileName, // ім'я файла
0, // отримання інформації про файл
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;
}
// отримаємо інформацію про файл
if (!GetFileInformationByHandle(hFile, &bhfi))
{
std::cerr << "Get file information by handle failed." << std::endl
<< "The last error code: " << GetLastError() << std::endl;
std::cout << "Press any key to finish.";
std::cin.get();
return 0;
}
// роздруковуємо інформацію про файл
std::cout << "File attributes: " << bhfi.dwFileAttributes << std::endl
<< "Creation time: high date: "
<< bhfi.ftCreationTime.dwHighDateTime << std::endl
<< "Creation time: low date: "
<< bhfi.ftCreationTime.dwLowDateTime << std::endl
<< "Last access time: high date: "
<< bhfi.ftLastAccessTime.dwHighDateTime << std::endl
<< "Last access time: low date: "
<< bhfi.ftLastAccessTime.dwLowDateTime << std::endl
<< "Last write time: high date: "
<< bhfi.ftLastWriteTime.dwHighDateTime << std::endl
<< "Last write time: low date: "
<< bhfi.ftLastWriteTime.dwLowDateTime << std::endl
<< "Volume serial number: " << bhfi.dwVolumeSerialNumber << std::endl
<< "File size high: " << bhfi.nFileSizeHigh << std::endl
<< "File size low: " << bhfi.nFileSizeLow << std::endl
<< "Number of links: " << bhfi.nNumberOfLinks << std::endl
<< "File index high: " << bhfi.nFileIndexHigh << std::endl
<< "File index low: " << bhfi.nFileIndexLow << std::endl;
// закриваємо дескриптор файла
CloseHandle(hFile);
std::cin.get();
return 0;
}
Структура типу by_handle_file_information містить структуру типу filetime, яка служить для зберігання часу. Ця структура має наступний формат:
typedef struct _FILETIME {
DWORD dwLowDateTime; // молодша частина часу
DWORD dwHighDateTime; // старша частина часу
} FILETIME, *PFILETIME;
Сам час задається в інтервалах, кожен з яких дорівнює 100 наносекунд. Природно, що такий час незручно переглядати користувачеві. Тому для переведення часу в зручнішу форму існує функція FileTimeToSystemTime(), Яка має наступний прототип:
BOOL FileTimeToSystemTime(
CONST FILETIME *lpFileTime, // покажчик на якийсь час у форматі "файл"
LPSYSTEMTIME IpSystemTime); // покажчик на якийсь час у форматі "система"
У разі успішного завершення ця функція повертає ненульове значення, інакше - false.
Параметр lpFileTime цієї функції повинен вказувати на структуру типу filetime, яка містить час у форматі, який використовується для зберігання у файловій системі.
Параметр IpSystemTime повинен вказувати на структуру типу systemtime, яка має наступний формат:
typedef struct _SYSTEMTIME {
WORD wYear; // рік
WORD wMonth; // місяць
WORD wDayOfWeek; // день тижня
WORD wDay; // день
WORD wHour; // година
WORD wMinute; // хвилина
WORD wSecond; // секунда
WORD wMilliseconds; // мілісекунда
} SYSTEMTIME, *LPSYSTEMTIME;
У лістингу 24.16 приведена програма, яка використовує функцію FileTimeToSystemTime() для переведення часу з формату файлової системи в системний формат.
// Лістинг 24.16. Перетворення часу в системний формат
#include "stdafx.h"
int main()
{
HANDLE hFile;
wchar_t lpszFileName[] = L"C:\\Users\\Shogun\\Documents\\demo_file.dat";
BY_HANDLE_FILE_INFORMATION bhfi; // інформація про файл
SYSTEMTIME st; // системний час
// відкриваємо файл для читання
hFile = CreateFile(
lpszFileName, // ім'я файла
0, // отримання інформації про файл
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;
}
// отримуємо інформацію про файл
if (!GetFileInformationByHandle(hFile, &bhfi))
{
std::cerr << "Get file information by handle failed." << std::endl
<< "The last error code: " << GetLastError() << std::endl;
std::cout << "Press any key to finish.";
std::cin.get();
return 0;
}
// переводимо час створення файла в системний час
if (!FileTimeToSystemTime(&(bhfi.ftCreationTime), &st))
{
std::cerr << "File time to system time failed." << std::endl
<< "The last error code: " << GetLastError() << std::endl;
std::cout << "Press any key to finish.";
std::cin.get();
return 0;
}
// роздруковуємо системний час
std::cout << "File creation time in system format: " << std::endl
<< "\tYear: " << st.wYear << std::endl
<< "\tMonth: " << st.wMonth << std::endl
<< "\tDay of week: " << st.wDayOfWeek << std::endl
<< "\tDay: " << st.wDay << std::endl
<< "\tHour: " << st.wHour << std::endl
<< "\tMinute: " << st.wMinute << std::endl
<< "\tSecond: " << st.wSecond << std::endl
<< "\tMilliseconds: " << st.wMilliseconds << std::endl;
// закриваємо дескриптор файла
CloseHandle(hFile);
std::cin.get();
return 0;
}
Визначити тип файла можна за допомогою функції GetFileType(), яка має наступний прототип:
DWORD GetFileType(
HANDLE hFile); // дескриптор файла
Єдиним параметром цієї функції є дескриптор файла. Функція GetFileType() повертає одне з наступних значень:
file_type_unknown - невідомий тип файла;
file_type_disk - дисковий файл;
file_type_char - символьний файл;
file_type_pipe - іменований або анонімний канал.
Відмітимо, що під символьним файлом зазвичай розуміється принтер або консоль.
У лістингу 24.17 приведена програма, яка визначає тип файла, використовуючи функцію GetFileType().
// Лістинг 24.17. Визначення типу файла
#include "stdafx.h"
int main()
{
HANDLE hFile;
wchar_t lpszFileName[] = L"C:\\Users\\Shogun\\Documents\\demo_file.dat";
DWORD dwFileType;
// відкриваємо файл для читання
hFile = CreateFile(
lpszFileName, // ім'я файла
0, // отримання інформації про файл
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;
}
// визначаємо тип файла
dwFileType = GetFileType(hFile);
// роздруковуємо тип файла
switch (dwFileType)
{
case FILE_TYPE_UNKNOWN:
std::cout << "Unknown type file." << std::endl;
break;
case FILE_TYPE_DISK:
std::cout << "Disk type file." << std::endl;
break;
case FILE_TYPE_CHAR:
std::cout << "Char type file." << std::endl;
break;
case FILE_TYPE_PIPE:
std::cout << "Pipe type file." << std::endl;
break;
default:
break;
}
std::cin.get();
return 0;
}
На платформі Windows NT можна визначити, чи є файл виконуваним. Для цього треба використовувати функцію GetBinaryType(), яка має наступний прототип:
BOOL GetBinaryType(
LPCTSTR lpApplicationName, // ім’я застосування
LPDWORD lpBinaryType); // тип виконуваного файла
Якщо файл є виконуваним, то функція повертає ненульове значення, інакше - false.
У параметрі lpApplicationName встановлюється покажчик на рядок, який містить ім’я файла, який перевіряється.
Параметр lpBinaryType повинен вказувати на змінну типу dword, в яку функція GetBinaryType() поміщає тип виконуваного файла. Цей тип може приймати одне з наступних значень:
scs_32bit_binary - застосування Win32;
scs_dos_binary - застосування MS-DOS;
scs_os216_binary - 16-бітове застосування OS/2;
scs_pif_binary - PIF-файл;
scs_posix_binary - застосування POSIX;
scs_wow_binary - 16-бітове застосування Windows.
У лістингу 24.18 приведена програма, яка визначає тип виконуваного файла, використовуючи функцію GetBinaryType().
// Лістинг 24.18. Визначення типу виконуваного файла
#include "stdafx.h"
int main()
{
DWORD dwBinaryType;
wchar_t lpszFileName[] = L"C:\\ConsoleProcess.exe";
// визначимо тип файла
if(!GetBinaryType(lpszFileName, &dwBinaryType))
{
std::cerr << "Get binary type failed." << std::endl
<< "The file may not be executable." << std::endl
<< "The last error code: " << GetLastError() << std::endl;
std::cout << "Press any key to finish.";
std::cin.get();
return 0;
}
// роздрукуємо тип файла
if (dwBinaryType == SCS_32BIT_BINARY)
std::cout << "The file is Win32 based application." << std::endl;
else
std::cout << "The file is not Win32 based application." << std::endl;
std::cin.get();
return 0;
}
