Приложение TestFile
Приложение TestFile
Теперь мы представим вам приложение, которое использует класс CStdioFile для записи в файл информации о файловой системе компьютера. Для определения характеристик файловой системы мы воспользовались функцией GetVolumeInformation из программного интерфейса Win32.
Эта функция позволяет определить различные характеристики файловой системы, установленной на данном томе. Ниже представлен прототип функции GetVolumeInformation:
BOOL GetVolumeInformation(LPCTSTR lpRootPathName, LPTSTR lpVolumeNameBuffer, DWORD nVolumeNameSize, LPDWORD lpVolumeSerialNumber, LPDWORD lpMaximumComponentLength, LPDWORD lpFileSystemFlags, LPTSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize);
Первый параметр lpRootPathName перед вызовом функции должен указывать на строку, содержащую путь корневого каталога тома, информацию о котором надо получить. Если вы присвоите lpRootPathName значение NULL, по умолчанию будет выбран корневой каталог текущего тома.
Параметр lpVolumeNameBuffer должен содержать указатель на буфер, в который будет записано имя тома. Длина буфера определяется параметром nVolumeNameSize. Если вас не интересует имя тома, вы можете указать для параметра lpVolumeNameBuffer значение NULL. В этом случае значение nVolumeNameSize не используется.
Параметр lpVolumeSerialNumber должен содержать адрес переменной типа DWORD, в которую будет записан серийный номер тома. Если вас не интересует серийный номер, вы можете указать для параметра значение NULL.
Параметр lpMaximumComponentLength должен содержать адрес переменной, в которую будет записана максимальная длина файла, для данной файловой системы. Для операционной системы Windows 95 эта переменная будет содержать значение 255, несмотря на то, что тип файловой системы остался FAT.
Параметр lpFileSystemFlags указывает на переменную, которая может быть одной или комбинацией нескольких констант, перечисленных в следующей таблице.
Константа Описание FS_CASE_IS_PRESERVED При записи файлов на диск сохраняется написание (заглавные и прописные символы) имени файла FS_CASE_SENSITIVE Файловая система различает заглавные и прописные символы в именах файлов FS_UNICODE_STORED_ON_DISK Файловая система обеспечивает кодировку имен файлов Unicode FS_FILE_COMPRESSION Обеспечивается возможность сжатия отдельных файлов, расположенных на томе. Эта константа не может быть использована вместе с другими FS_VOL_IS_COMPRESSED Данный том является компрессованным. Такой том может быть создан системами типа DoubleSpace. Эта константа не может быть использована вместе с другимиПараметр lpFileSystemNameBuffer содержит указатель на буфер, в который будет записан тип файловой системы. В зависимости от типа файловой системы, установленной на данном томе, это может быть FAT, NTFS или HPFS.
Размер буфера определяется параметром nFileSystemNameSize. Если вас не интересует тип файловой системы, запишите в параметр lpFileSystemNameBuffer значение NULL.
Если функция GetVolumeInformation завершилась без ошибок, она возвращает значение TRUE. В противном случае возвращается значение FALSE, а для получения дополнительной информации вы можете вызвать функцию GetLastError.
В листинге 3.1 представлен исходный текст приложения TestFile. В этом приложении используются всего несколько классов библиотеки классов MFC. Для организации самого приложения мы наследовали от базового класса CWinApp главный класс приложения CMFStartApp. Класс CWinApp был описан нами ранее в разделе “Приложение MFStart”.
В классе CMFStartApp определены два метода: InitInstance и FileSystemInfo. Метод InitInstance является переопределением виртуального метода InitInstance базового класса CWinApp. Этот метод вызывается каждый раз при запуске приложения. Мы используем метод InitInstance для того, чтобы вызвать метод FileSystemInfo и сразу завершить работу приложения.
Метод FileSystemInfo получает данные о файловой системе текущего тома и записывает их в файл fsystem.dat в текущем каталоге. Для получения информации о файловой системе используется функция GetVolumeInformation, описанная выше.
Данные, полученные функцией FileSystemInfo, временно заносятся в строку strTmpOut класса CString. При этом используется метод Format, чтобы получить форматированную запись, содержащую дополнительное текстовое описание.
Для записи в файл мы создали объект класса CStdioFile. В конструкторе мы сразу указали имя файла, который надо создать и открыть. Все операции с файлом, включая его создание, выполняются в блоке try. В случае возникновении ошибки во время создания или других операций с файлом вызывается исключение, которое будет обработано блоком catch.
Мы специально создаем файл и открываем его, используя конструктор класса CStdioFile, а не метод Open. Метод Open в случае возникновения ошибки возвращает соответствующее значение, но не вызывает исключение. Поэтому надо было бы специально проверять значение возвращаемое методом Open.
Для записи в файл мы вызываем метод WriteString, передавая ему в качестве параметра строку strTmpOut, которая содержит данные подготовленные для записи. Каждый вызов метода WriteString записывает в файл одну строку, так как в конце strTmpOut мы всегда записываем символ перевода строки.
Чтобы закрыть файл, мы используем метод Close базового класса CFile. В случае успешного завершения на экране отображается сообщение с именем файла fsystem.dat и управление возвращается методу InitInstance.
Если при работе с файлом возникла ошибка, управление передается блоку catch. В нем отображается сообщение об ошибке, а затем управление сразу возвращается методу InitInstance. Невыполненная часть блока try игнорируется.
Листинг 3.1. Файл TestFile.cpp
// Включаемый файл для MFC
#include <afxwin.h>
//=====================================================
// Главный класс приложения CMFStartApp
//=====================================================
class CMFStartApp : public CWinApp {
public:
virtual BOOL InitInstance();
void FileSystemInfo();
};
// Создаем объект приложение класса CMFStartApp
CMFStartApp MFStartApp;
//=====================================================
// Переопределяем виртуальный метод InitInstance
// класса CWinApp
//=====================================================
BOOL CMFStartApp::InitInstance() {
// Определяем характеристики файловой системы
FileSystemInfo();
// Завершаем приложение
return FALSE;
}
//=====================================================
// Метод FileSystemInfo главного класса приложения
// Определяет характеристики текущего тома и записывает
// их в файл
//=====================================================
void CMFStartApp::FileSystemInfo() {
// Метка тома
CString VolumeNameBuffer;
// Максимальная длина метки тома
DWORD nVolumeNameSize = 100;
// Серийный номер тома
DWORD VolumeSerialNumber;
// Максимальная длина имени файла
DWORD MaximumComponentLength;
// Характеристики файловой системы
DWORD FileSystemFlags;
// Тип файловой системы
CString FileSystemNameBuffer;
// Максимальная длина строки типа файловой системы
DWORD nFileSystemNameSize = 100;
// Получаем данные о файловой системе и текущем устройстве
GetVolumeInformation(NULL, VolumeNameBuffer.GetBuffer(nVolumeNameSize), nVolumeNameSize, &VolumeSerialNumber, &MaximumComponentLength, &FileSystemFlags, FileSystemNameBuffer.GetBuffer(nFileSystemNameSize), nFileSystemNameSize);
// Снимаем блокировку буферов
VolumeNameBuffer.ReleaseBuffer();
FileSystemNameBuffer.ReleaseBuffer();
// Обрабатываем ошибочные ситуации, которые могут
// возникнуть при работе с файлами
try {
// Создаем файл fsystem.dat и открываем его для записи
CStdioFile file("fsystem.dat", CFile::modeCreate | CFile::modeWrite | CFile::typeText);
// Временная строка, используемая для записи в файл
CString strTmpOut;
// Увеличиваем размер буфера до 512 байт
strTmpOut.GetBuffer(512);
// Записываем в файл метку тома
strTmpOut.Format("Метка тома: %s ", VolumeNameBuffer);
file.WriteString(strTmpOut);
// Записываем в файл серийный номер
strTmpOut.Format("Серийный номер: %X ", VolumeSerialNumber);
file.WriteString(strTmpOut);
// Записываем в файл тип файловой системы
strTmpOut.Format("Тип файловой системы: %s ", FileSystemNameBuffer);
file.WriteString(strTmpOut);
// Записываем в файл максимальную длину имени файла
strTmpOut.Format("Максимальная длина имени файла: %d ", MaximumComponentLength);
file.WriteString(strTmpOut);
// Записываем в файл свойства файловой системы
strTmpOut = "Свойства файловой системы ";
if (FileSystemFlags & FS_CASE_IS_PRESERVED) strTmpOut += " FS_CASE_IS_PRESERVED ";
if (FileSystemFlags & FS_CASE_SENSITIVE) strTmpOut += " FS_CASE_SENSITIVE ";
if (FileSystemFlags & FS_UNICODE_STORED_ON_DISK) strTmpOut += " FS_UNICODE_STORED_ON_DISK ";
if (FileSystemFlags & FS_PERSISTENT_ACLS) strTmpOut += " FS_PERSISTENT_ACLS ";
if (FileSystemFlags & FS_FILE_COMPRESSION) strTmpOut += " FS_FILE_COMPRESSION ";
if (FileSystemFlags & FS_VOL_IS_COMPRESSED) strTmpOut += " FS_VOL_IS_COMPRESSED ";
file.WriteString(strTmpOut);
// Закрываем файл
file.Close();
// Отображаем сообщение об успешном завершении приложения
MessageBox(NULL, "File fsystem.dat", "Message", MB_OK);
}
// Обработчик исключения. Вызывается при ошибках
// работы с файлами
catch(...) {
// Отображаем сообщение о возникшей ошибке
MessageBox(NULL, "File I/O Error", "Error", MB_OK);
}
return;
}
Файл fsystem.dat, созданный приложением, можно просмотреть в любом текстовом редакторе, например Notepad или WordPad. В листинге 3.2 приведен пример файла, полученного при помощи приложения TestFile на нашем компьютере, на котором установлена операционная система Windows 95.
Листинг 3.2. Файл fsystem.dat
Метка тома: LIBRARY
Серийный номер: 1D794E8D
Тип файловой системы: FAT
Максимальная длина имени файла: 255
Свойства файловой системы
FS_CASE_IS_PRESERVED
FS_UNICODE_STORED_ON_DISK