Чтобы получить информацию о файле, можно использовать функцию:
GetFilelnformationByHandle (
HANDLE hFile, // дескриптор файла
// указатель на информацию
LPBY_HANDLE_FILE_INFORMATION lpFilelnformation
);
Параметр lpFilelnformation должен указывать на структуру типа LPBY_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 nFileIndexLow; // младшая часть индекса файла
} BY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION;
Листинг 1. Пример приложения, демонстрирующего просмотр и изменение атрибутов файла.
#include <windows.h>
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <math.h>
using namespace std;
HANDLE creatfile(char* buf)
{
HANDLE hFile= CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ |FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
cerr << "Open file failed." << endl
<< "The last error code: " << GetLastError();
cout << "\nPress any key to finish.";
getch();
return hFile;
}
cout << "The file is opened." << endl;
//CloseHandle(hFile);
return hFile;
}
char * getfileattributes(char* lpFileName)
{
char cBuffer[0x1000]="";
DWORD dwFileAttributes=GetFileAttributes(lpFileName);
cout << endl<< lpFileName << " - 0x" << hex << dwFileAttributes << ": ";
dec(cout);
for(int i = 31; i >= 0; i--) if(dwFileAttributes & (1 << i)) cout << "1"; else cout << "0";
if(dwFileAttributes & FILE_ATTRIBUTE_READONLY) strcat(cBuffer, "\n\tFILE_ATTRIBUTE_READONLY");
if(dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) strcat(cBuffer,"\n\t FILE_ATTRIBUTE_HIDDEN");
if(dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) strcat(cBuffer, "\n\tFILE_ATTRIBUTE_SYSTEM");
if(dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) strcat(cBuffer,"\n\t FILE_ATTRIBUTE_DIRECTORY");
if(dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) strcat(cBuffer,"\n\t FILE_ATTRIBUTE_ARCHIVE");
if(dwFileAttributes & FILE_ATTRIBUTE_NORMAL) strcat(cBuffer,"\n\t FILE_ATTRIBUTE_NORMAL");
if(dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) strcat(cBuffer,"\n\t FILE_ATTRIBUTE_TEMPORARY");
if(dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) strcat(cBuffer,"\n\t FILE_ATTRIBUTE_COMPRESSED");
if(dwFileAttributes & FILE_FLAG_POSIX_SEMANTICS) strcat(cBuffer,"\n\t FILE_FLAG_POSIX_SEMANTICS");
if(dwFileAttributes & FILE_FLAG_BACKUP_SEMANTICS) strcat(cBuffer,"\n\t FILE_FLAG_BACKUP_SEMANTICS");
if(dwFileAttributes & FILE_FLAG_DELETE_ON_CLOSE) strcat(cBuffer, "\n\t FILE_FLAG_DELETE_ON_CLOSE");
if(dwFileAttributes & FILE_FLAG_SEQUENTIAL_SCAN) strcat(cBuffer,"\n\t FILE_FLAG_SEQUENTAL_SCAN");
if(dwFileAttributes & FILE_FLAG_RANDOM_ACCESS) strcat(cBuffer,"\n\t FILE_FLAG_RANDOM_ACCESS");
if(dwFileAttributes & FILE_FLAG_NO_BUFFERING) strcat(cBuffer,"\n\t FILE_FLAG_NO_BUFFERING");
if(dwFileAttributes & FILE_FLAG_OVERLAPPED) strcat(cBuffer,"\n\t FILE_FLAG_OVERLAPPED");
if(dwFileAttributes & FILE_FLAG_WRITE_THROUGH) strcat(cBuffer,"\n\t FILE_FLAG_WRITE_THROUGH");
return cBuffer;
}
bool setfileattributes(char* lpFileName)
{
DWORD adwFileAttributes[16]={
FILE_ATTRIBUTE_READONLY,
FILE_ATTRIBUTE_HIDDEN,
FILE_ATTRIBUTE_SYSTEM,
FILE_ATTRIBUTE_DIRECTORY,
FILE_ATTRIBUTE_ARCHIVE,
FILE_ATTRIBUTE_NORMAL,
FILE_ATTRIBUTE_TEMPORARY,
FILE_ATTRIBUTE_COMPRESSED,
FILE_FLAG_POSIX_SEMANTICS,
FILE_FLAG_BACKUP_SEMANTICS,
FILE_FLAG_DELETE_ON_CLOSE,
FILE_FLAG_SEQUENTIAL_SCAN,
FILE_FLAG_RANDOM_ACCESS,
FILE_FLAG_NO_BUFFERING,
FILE_FLAG_OVERLAPPED,
FILE_FLAG_WRITE_THROUGH
};
int i,set;
DWORD dwFileAttributes=GetFileAttributes(lpFileName);
while (1)
{
system("cls");
cout<<getfileattributes(lpFileName)<<endl;
cout << "\nATTRIBUTES:\n";
cout << "\tFILE_ATTRIBUTE_READONLY - 1" << endl;
cout << "\tFILE_ATTRIBUTE_HIDDEN - 2"<< endl;
cout << "\tFILE_ATTRIBUTE_SYSTEM - 3"<< endl;
cout << "\tFILE_ATTRIBUTE_DIRECTORY - 4"<< endl;
cout << "\tFILE_ATTRIBUTE_ARCHIVE - 5"<< endl;
cout << "\tFILE_ATTRIBUTE_NORMAL - 6"<< endl;
cout << "\tFILE_ATTRIBUTE_TEMPORARY - 7"<< endl;
cout << "\tFILE_ATTRIBUTE_COMPRESSED - 8"<< endl;
cout << "\tFILE_FLAG_POSIX_SEMANTICS - 9"<< endl;
cout << "\tFILE_FLAG_BACKUP_SEMANTICS- 10"<< endl;
cout << "\tFILE_FLAG_DELETE_ON_CLOSE - 11"<< endl;
cout << "\tFILE_FLAG_SEQUENTIAL_SCAN - 12"<< endl;
cout << "\tFILE_FLAG_RANDOM_ACCESS - 13"<< endl;
cout << "\tFILE_FLAG_NO_BUFFERING - 14"<< endl;
cout << "\tFILE_FLAG_OVERLAPPED - 15"<< endl;
cout << "\tFILE_FLAG_WRITE_THROUGH - 16"<< endl;
cout << "\nType a number!(1..16 - change attribute/0 - return for main menu) ";
cin >> i;
if (!i) return 0;
else
{
cout << "\nType '1' to set attrebut and '0' to unset!(1/0) ";
cin >> set;
if(set==0) {dwFileAttributes=dwFileAttributes ^ adwFileAttributes[i-1]; } else
if(set==1) {dwFileAttributes=dwFileAttributes | adwFileAttributes[i-1];}
cout << endl<< "0x" << hex << dwFileAttributes << ": ";
dec(cout);
for(int i = 31; i >= 0; i--) if(dwFileAttributes & (1 << i)) cout << "1"; else cout << "0";
getch();
if(!SetFileAttributes(lpFileName,dwFileAttributes))
cerr << "Set File Attributes failed." << endl
<< "The last error code: " << GetLastError();
}
}
}
int main()
{
char buf[256],FileName[256]="";
HANDLE hFile;
DWORD lpFileSizeHigh;
BY_HANDLE_FILE_INFORMATION fi;
FILETIME ft;SYSTEMTIME st;
int iMenu;char cMenu[200]="ВЫБЕРИТЕ ДЕЙСТВИЕ:\n1 - ПРОСМОТРЕТЬ/ИЗМЕНИТЬ АТРИБУТЫ ФАЙЛА\n2 - ПОСМОТРЕТЬ/ИЗМЕНИТЬ РАЗМЕР ФАЙЛА\n3 - БЛОКИРОВАТЬ/РАЗБЛОКИРОВАТЬ ФАЙЛ\n4 - ПОСМОТРЕТЬ ИНФОРМАЦИЮ О ФАЙЛЕ\n5 - ВЫЙТИ\n;
CharToOem(cMenu, cMenu);
CharToOem("Iм'я файлу?\n", buf); cout << buf; cin >> FileName;
if ((hFile=creatfile(FileName))!=INVALID_HANDLE_VALUE)
while(1)
{
system("cls");
cout << cMenu; cin >> iMenu;
switch(iMenu)
{
case 1:
CharToOem("АТРИБУТЫ ФАЙЛА:\n", buf); cout << buf;
cout<<getfileattributes(FileName)<<endl;
CharToOem("\nИзменить атрибуты?(y/n) ",buf); cout << buf; cin >> buf;
if(*buf=='y') setfileattributes(FileName);
break;
case 2:
CharToOem("РАЗМЕР ФАЙЛА:\n", buf); cout << buf;
cout<<FileName<<" - "<<(floor(((double)GetFileSize(hFile,&lpFileSizeHigh)/1024)*100)/100)<< " KB" <<endl;
CharToOem("\nИзменить размер?(y/n) ",buf); cout << buf; cin >> buf;
if(*buf=='y')
{
CharToOem("Новый размер? ", buf); cout << buf;cin >>lpFileSizeHigh;
SetFilePointer(hFile,lpFileSizeHigh,NULL,FILE_BEGIN);
if(SetEndOfFile(hFile)) cout<<"size changed";
else cerr<<"size chang failed"<< endl
<<"The last error code: "<< GetLastError();
}
cout<<"\nPress any key to continue!";
getch();
break;
case 3:
CharToOem("ДОСТУП К ФАЙЛУ:\n\tблокировать - 1\n\tразблокировать - 2\n", buf); cout << buf;cin>>buf;
if (*buf=='1')
{
if(LockFile(hFile,0,0,GetFileSize(hFile,&lpFileSizeHigh),0)) cout << "file locked";
else cerr<<"file lock filed"<< endl
<<"The last error code: "<< GetLastError();
}else
if (*buf=='2')
{
if(UnlockFile(hFile,0,0,GetFileSize(hFile,&lpFileSizeHigh),0)) cout << "file unlocked";
else cerr<<"file unlock filed"<< endl
<<"The last error code: "<< GetLastError();
}
cout<<"\nPress any key to continue!";
getch();
break;
case 4:
CharToOem("ИНФОРМАЦИЯ О ФАЙЛЕ:\n", buf); cout << buf;
if(GetFileInformationByHandle(hFile,&fi))
{
cout << endl << "ATTRIBUTES:" <<endl;
if(fi.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) cout<<"\tFILE_ATTRIBUTE_ARCHIVE\n";
if(fi.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) cout<<"\tFILE_ATTRIBUTE_COMPRESSED\n";
if(fi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) cout<<"\tFILE_ATTRIBUTE_DIRECTORY\n";
if(fi.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) cout<<"\tFILE_ATTRIBUTE_HIDDEN\n";
if(fi.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) cout<<"\tFILE_ATTRIBUTE_NORMAL\n";
if(fi.dwFileAttributes & FILE_ATTRIBUTE_READONLY) cout<<"\tFILE_ATTRIBUTE_READONLY\n";
if(fi.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) cout<<"\tFILE_ATTRIBUTE_SYSTEM\n";
if(fi.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) cout<<"\tFILE_ATTRIBUTE_TEMPORARY\n";
FileTimeToSystemTime(&fi.ftCreationTime, &st);
cout<<endl<<"FILE TIME:"<<endl
<<"\tCreation Time "<<st.wYear<<"-"<<st.wMonth<<"-"<<st.wDay<<" "<<st.wHour<<":"<<st.wMinute<<":"<<st.wSecond<<endl;
FileTimeToSystemTime(&fi.ftLastAccessTime, &st);
cout<<"\tLast Access "<<st.wYear<<"-"<<st.wMonth<<"-"<<st.wDay<<" "<<st.wHour<<":"<<st.wMinute<<":"<<st.wSecond<<endl;
FileTimeToSystemTime(&fi.ftLastWriteTime, &st);
cout<<"\tLast Write "<<st.wYear<<"-"<<st.wMonth<<"-"<<st.wDay<<" "<<st.wHour<<":"<<st.wMinute<<":"<<st.wSecond<<endl;
cout<<endl
<<"Volume Serial Number "<<fi.dwVolumeSerialNumber<<endl;
cout<<"File Size "<<(floor(((double)fi.nFileSizeLow/1024)*100)/100)<< " KB" <<endl;
cout<<"Number Of Links "<<fi.nNumberOfLinks<<endl;
cout<<"File Index (Low High) "<<fi.nFileIndexLow<<" "<<fi.nFileIndexHigh<<endl;
}
else cerr<<"Get file information filed"<< endl
<<"The last error code: "<< GetLastError();
cout<<"\nPress any key to continue!";
getch();
break;
case 5: CloseHandle(hFile);return 0;
}
}
return 0;
}
Задание на выполнение
1. Написать программу в которой были бы реализованы следующие функции работы с файлами:
− определение и изменение атрибутов файла;
− определение и изменение размеров файла;
− блокирование файла;
− получение информации о файле.
2. Выбор функции организовать в виде меню, пути до файлов вводить с клавиатуры.
3. Ознакомится с основными параметрами данных функций, исследовать их работу при изменении основных параметров.
Контрольные вопросы
1. Какие существуют функции для работы со временем?
2. Какие значения атрибутов имеют файлы и какой функцией они устанавливаются?
3. Какой функцией можно изменить атрибуты файлов?
4. Какая функция создает имена для временных файлов?
Лабораторная работа №10
Тема: Работа с каталогами с помощью Win32 API функций
Цель работы:
1.Изучение основных функций Win32API, используемых для работы с каталогами.
2. Разработка приложения, демонстрирующего создание, удаление и перемещение каталогов, поиск файлов и наблюдение за каталогом.
Краткое теоретическое введение
Создание каталога
Для создания каталога используется функция:
BOOL CreateDirectory(
LPCTSTR lpPathName, // имя каталога
LPSECUTITY_ATTRIBUTES lpSecurutyAttributes // атрибуты защиты
);
Для создания подкаталогов можно использовать функцию CreateDirectoryEx.
BOOL CreateDirectoryEx(
LPCSTR lpTemplateDirectory, // имя шаблонного каталога
LPCTSTR lpNewDirectory, // имя нового каталога
LPSECUTITY_ATTRIBUTES lpSecurutyAttributes // атрибуты защиты
);
Поиск файлов в каталоге
Для поиска файлов, находящихся в каталоге, используются функции:
HANDLE FindFirstFile(
LPCTSTR lpFileName, // образец имени для поиска
LPWIN32_FIND_DATA lpFindFileData // адрес данных о файле
);
В случае успешного завершения функция FindFirstFile возвращает дескриптор для поиска файлов, который используется в дальнейшем функцией FindNextFile, а в случае неудачи — значение INVALID_HANDLE_VALUE.
ПараметрlpFindFileData должен указывать на структуру типа WIN32_FIND_DATA:
typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes; // атрибуты файла
FILETIME ftCreationTime; // время создания файла
FILETIME ftLastAccessTime; //время последнего доступа к файлу
FILETIME ftLastWriteTime; // время последней записи в файл
DWORD nFileSizeHigh; // старшая часть размера файла
DWORD nFileSizeLow; // младшая часть размера файла
DWORD dwReserved0; // тег для преобразования файла
DWORD dwReservedl; // не используется
CHAR cFileName[ MAX_PATH ]; // длинное имя файла
CHAR cAlternateFileName[ 14 ]; // короткое имя файла
} WIN32_FIND_DATA, *PWIN32_FIND_DATA, *LPWIN32_FIND_DATA;
FindNextFile:
BOOL FindNextFile (
HANDLE hFindFile, // дескриптор для поиска файлов
LPWIN32_FIND_DATA lpFindFileData // адрес данных о файле
);
Кроме того, отметим, что после завершения поиска файлов нужно вызвать функцию FindClose, которая закрывает дескриптор поиска файлов:
BOOL FindClose(
HANDLE hFindFile // дескриптор поиска файла
);
Удаление каталога
Для удаления пустого каталога предназначена функция:
BOOL RemoveDirectory(
LPCTSTR lpPathName // имя каталога
);
Перемещение каталога
BOOL MoveFile(
LPCTSTR lpExistingFileName, // имя существующего файла
LPCTSTR lpNewFileName // имя нового файла);