Получение информации о файле

Чтобы получить информацию о файле, можно использовать функцию:

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 // имя нового файла );