Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
24 Робота з файлами у Windows.docx
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
559 Кб
Скачать
☆

24.12. Визначення і зміна розмірів файла

Перш ніж описувати функції для роботи з розміром файла, зауважимо, що розмір файла є цілим числом і для його зберігання вимагаються два значення типу dword або, іншими словами, два подвійні слова. Перше з цих подвійних слів містить старшу частину розміру файла, а друге - молодшу. Якщо розмір файла входить тільки в молодшу частину, то значення старшою встановлюється в null.

Визначити розмір файла можна за допомогою функції GetFileSize(), яка має наступний прототип:

DWORD GetFileSize(

HANDLE hFile, // дескриптор файла

LPDWORD lpFileSizeHigh); // покажчик на старшу частину розміру файла

У разі успішного завершення ця функція повертає молодшу частину розміру файла, а за адресою, вказаною в параметрі lpFileSizeHigh, записує старшу частину розміру файла. У разі невдачі функція GetFileSize() повертає значення -1, якщо значення адреси, заданої параметром lpFileSizeHigh, встановлене в null. Якщо ж значення цієї адреси не дорівнює null і функція закінчилася невдачею, то вона повертає значення -1 і функція коду останньої помилки GetLastError() поверне значення, відмінне від no_error.

Відмітимо, що для правильної роботи функції GetFileSize() потрібне, щоб файл був відкритий в режимі читання або запису.

У лістингу 24.11 приведена програма, яка визначає розмір файла, використовуючи функцію GetFileSize().

// Лістинг 24.11. Визначення розміру файла за допомогою функції GetFileSize()

#include "stdafx.h"

int main()

{

HANDLE hFile;

wchar_t lpszFileName[] = L"C:\\Users\\Shogun\\Documents\\demo_file.dat";

DWORD dwFileSize; // молодша частина розміру файла

// відкриваємо файл для читання

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;

}

// визначаємо розмір файла

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;

}

// виводимо розмір файла

std::cout << "File size: " << dwFileSize << std::endl;

// закриваємо дескриптор файла

CloseHandle(hFile);

std::cin.get();

return 0;

}

Визначити розмір файла можна також за допомогою функції GetFileSizeEx(), яка підтримується тільки ОС Windows 2000 і Windows XP. Ця функція має наступний прототип:

BOOL GetFileSizeEx(

HANDLE hFile, // дескриптор файла

PLARGE_INTEGER lpFileSize); // розмір файла

У разі успішного завершення функція повертає ненульове значення, інакше - false.

Параметр hFile цієї функції повинен містити дескриптор файла, а параметр lpFileSize вказує на об’єднання типу large_integer, в яке функція GetFileSizeEx() записує розмір файла. Формат об’єднання типу large_integer приведений в розд. 24.10.

У лістингу 24.12 приведена програма, яка визначає розмір файла, використовуючи функцію GetFileSizeEx().

// Лістинг 24.12. Визначення розміру файла за допомогою функції GetFileSizeEx()

#include "stdafx.h"

int main()

{

HANDLE hFile;

wchar_t lpszFileName[] = L"C:\\Users\\Shogun\\Documents\\demo_file.dat";

LARGE_INTEGER liFileSize; // розмір файла

// відкриваємо файл для читання

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;

}

// визначаємо розмір файла

if (!GetFileSizeEx(hFile, &liFileSize))

{

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;

}

// виводимо розмір файла

std::cout << "File size: " << liFileSize.LowPart << std::endl;

// закриваємо дескриптор файла

CloseHandle(hFile);

std::cin.get();

return 0;

}

Змінити розмір файла можна за допомогою функції SetEndOfFile(), яка має наступний прототип:

BOOL SetEndOfFile(

HANDLE hFile); // дескриптор файла

У разі успішного завершення ця функція повертає ненульове значення, інакше - false. Єдиним параметром функції є дескриптор файла, розмір якого змінюється. При цьому відмітимо, що файл має бути відкритий в режимі запису.

Функція SetEndOfFile() працює таким чином. Вона пересуває маркер кінця файла eof на позицію, яку містить покажчик позиції файла. Якщо покажчик позиції файла вказує на запис, який не є останнім, то всі записи, які знаходяться за поточним записом, відкидаються. Таким чином, у цьому випадку вміст файла урізається.

Якщо ж покажчик позиції файла вказує за межі файла, то обсяг файла розширюється за рахунок додавання нових кластерів до нього. При цьому вміст доданих кластерів не визначений. У лістингу 24.13 наведений приклад програми, яка зменшує розмір файла в два рази.

// Лістинг 24.13. Зміна розміру файла

#include "stdafx.h"

int main()

{

HANDLE hFile; // дескриптор файла

wchar_t lpszFileName[] = L"C:\\Users\\Shogun\\Documents\\demo_file.dat";

DWORD dwFileSize; // розмір файла

long p; // покажчик позиції

// відкриваємо файл для читання

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;

}

// виводимо на консоль розмір файла

std::cout << "Old file size: " << dwFileSize << std::endl;

// зменшуємо розмір файла вдвічі

dwFileSize /= 2;

// зсуваємо покажчик позиції файла

p = SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN);

if(p == -1)

{

std::cerr << "Set file pointer 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 (!SetEndOfFile(hFile))

{

std::cerr << "Set end of 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;

}

// визначаємо новий розмір файла

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;

}

// виводимо на консоль розмір файла

std::cout << "New file size: " << dwFileSize << std::endl;

// закриваємо дескриптор файла

CloseHandle(hFile);

std::cin.get();

return 0;

}

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