<{{./BAN/TOPBAN}}> Media TT

Программирование
Генеалогия

<{{./BAN/ARTIC5}}>
<{{./BAN/ARTICDN}}>
И снова мы вернулись к такой избитой, но такой интересной и необходимой теме - работа с файлами... В современном программировании практически не встречаются приложения, которые не сохраняют какие-нибудь постоянные или временные данные на диск, в базу данных или в реестр. Таким образом, уметь работать с файлами важно для любого уважающего себя программиста.

В данном разделе мы рассмотрим классы для работы с дисковыми файлами: класс CFile и класс, производный от него, CStdioFile. В процессе изучения вы найдете множество моментов, схожих с использованием библиотеки fstream.h в Windows Console Application.

CFile

Инициализация

CFile( );                // Конструктор по умолчанию

CFile( int hFile );      // Параметр hFile - дескриптор уже открытого файла

CFile( LPCTSTR lpszFileName, UINT nOpenFlags );

// lpszFileName - путь к открываемому файлу, путь может быть абсолютным

// или относительным; nOpenFlags - флаги, указывающие режим совместного

// использования файла и режим открытия файла. Флаги можно комбинировать

// с помощью операции побитового или (|). Один режим открытия файла и

// один режим совместного использования файла обязательны.

// Значения флагов:

// CFile::modeCreate - создание нового файла; если файл уже существует,

// то он обрезается до нулевой длины

// CFile::modeNoTruncate - комбинируется с modeCreate - если создаваемый

// файл уже существует, то он не обрезается до нулевой длины

// CFile::modeRead - открывает файл только для чтения

// CFile::modeWrite - открывает файл только для записи

// CFile::modeReadWrite - открывает файл для чтения/записи

// CFile::modeNoInherit - запрещает дочерним процессам наследование файла

// CFile::shareDenyNone - открывает файл, не запрещая другим процессам

// чтение/запись

// CFile::shareDenyRead - открывает файл, другие процессы могут открывать

// этот файл только для чтения

// CFile::modeDenyWrite - открывает файл, другие процессы могут открывать

// этот файл только для записи

// CFile::shareExclusive - открывает файл в монопольном режиме, запрещая

// другим процессам чтение/запись

// CFile::typeText - устанавливает текстовый режим со специальной

// обработкой пар символов конца/перевода строки

// CFile::typeBinary - устанавливает двоичный режим

Примечание:

если в процессе открытия файла произошла ошибка, то возбуждается

исключительная ситуация.

virtual void Abort( );

// Закрывает файл, игнорируя любые предупреждения и ошибки. Если вы не

// закрыли файл до разрушения объекта, деструктор сделает это за вас.

// Если вы создаете объект класса CFile динамически, не забудьте

// удалить его после закрытия файла.

Примечание:

функция Abort имеет два отличия от функции Close: во-первых, в случае

ошибки функция Abort не возбудит исключительную ситуацию, т. к. она

игнорирует любые ошибки; во-вторых, она абсолютно спокойно реагирует

на ситуацию, когда файл не был предварительно открыт или уже был закрыт.

virtual CFile* Duplicate( ) const;

// Создает файловый объект-дубликат для данного файла.

virtual BOOL Open ( LPCTSTR lpszFileName, UINT nOpenFlags,

                   CFileException* pError = NULL );

// Производит безопасное открытие файла с возможностью проверки ошибок.

// Возвращает ненулевое значение, если открытие прошло успешно; иначе -

// возвращает 0 (параметр pError имеет смысл только в этом случае).

// lpszFileName - строка, содержащая путь к файлу; путь может быть

// абсолютным, относительным или сетевым.

// nOpenFlags - набор флагов, которые указывают режим совместного

// использования файла и режим открытия файла (см. конструктор класса).

// pError - указатель на существующий объект класса файловых исключений,

// получает статус неудачной операции (этого не происходит, если

// pError = NULL).

 

virtual void Close( );

// Закрывает файл. Если вы не закрыли файл до разрушения объекта,

// деструктор сделает это за вас.

// Если вы создаете объект класса CFile динамически, не забудьте

// удалить его после закрытия файла.

// В случае возникновения ошибки возбуждает исключительную ситуацию.

Ввод-вывод

virtual UINT Read ( void* lpBuf, UINT nCount );

// Читает данные из файла, начиная с текущей позиции.

// Возвращает количество считанных байт. Количество может быть меньше

// параметра nCount, если был достигнут конец файла.

// lpBuf - буфер, в который записываются считанные из файла данные.

// nCount - максимальное количество считываемых байт за один раз.

// Для текстовых режимов пара символов конец/перевод строки считается

// как один символ!

// В случае возникновения ошибки возбуждает исключительную ситуацию.

 

virtual void Write( const void* lpBuf, UINT nCount );

// Записывает данные из буфера lpBuf в файл.

// lpBuf - буфер, в котором хранятся данные для записи в файл.

// nCount - максимальное количество записываемых байт за один раз.

// Для текстовых режимов пара символов конец/перевод строки считается

// как один символ!

// В случае возникновения ошибки возбуждает исключительную ситуацию.

 

virtual void Flush( );

// Выполняет отложенную запись всех данных.

// В случае возникновения ошибки возбуждает исключительную ситуацию.

Позиционирование

virtual LONG Seek ( LONG lOff, UINT nFrom );

// Перемещает файловый указатель в заданную позицию.

// Если заданная позиция корректна, то возвращается новое смещение

// относительно начала файла, если нет, то возвращаемое значение

// неопределено и возбуждается исключительная ситуация.

// lOff - количество байт для перемещения указателя.

// nFrom - откуда перемещать. Варианты:

// CFile::begin - относительно начала файла,

// CFile::current - относительно текущей позиции файлового указателя,

// CFile::end - относительно конца файла (параметр lOff должен быть

// отрицательным).

 

void SeekToBegin( );

// Перемещает файловый указатель в начало файла.

// В случае ошибки (например, файл закрыт) возбуждается исключительная

// ситуация.

 

DWORD SeekToEnd( );

// Перемещает файловый указатель в начало файла.

// Возвращает длину файла в байтах.

// В случае ошибки (например, файл закрыт) возбуждается исключительная

// ситуация.

 

virtual DWORD GetLength( ) const;

// Возвращает текущую логическую длину файла (не размер).

// В случае ошибки возбуждается исключительная ситуация.

 

virtual void SetLength( DWORD dwNewLen );

// Устанавливает новую длину файла (параметр dwNewLen). В зависимости

// от значения параметра файл расширяется или усекается.

// В случае ошибки возбуждается исключительная ситуация.

Блокировка

virtual void LockRange( DWORD dwPos, DWORD dwCount );

// Блокировка заданного диапазона байт для других процессов в открытом

// файле. Если файл уже блокирован, возбуждается исключительная

// ситуация. Пользователь имеет возможность блокировать несколько

// неперекрывающихся (!) диапазонов байт. При разблокировке диапазона

// с помощью функции UnlockRange разблокированный диапазон должен

// точно совпадать с заблокированным ранее диапазоном. Если были

// заблокированы смежные диапазоны, то разблокировать их необходимо по

// отдельности.

// dwPos - начальный элемент диапазона,

// dwCount - количество элементов в диапазоне.

 

virtual void UnlockRange( DWORD dwPos, DWORD dwCount );

// Разблокировка заданного диапазона байт в открытом файле. Если файл

// уже блокирован, возбуждается исключительная ситуация.

// (см. описание функции LockRange).

Информация

virtual DWORD GetPosition( ) const;

// Возвращает текущую позицию файлового указателя.

// В случае ошибки возбуждается исключительная ситуация.

 

BOOL GetStatus( CFileStatus& rStatus ) const;

// Возвращает истину, если информация о файле получена, иначе - ложь.

// (Файл уже должен быть открыт!).

// rStatus - ссылка на объе кт структуры CFileStatus, поля которой

// заполняются полученной информацией. Поля:

// CTime m_ctime - дата и время создания файла,

// CTime m_mtime - дата и время последней модификации файла,

// CTime m_atime - дата и время последнего открытия файла на чтение,

// LONG m_size - логический размер файла в байтах (как по команде DIR),

// BYTE m_attribute - байт атрибутов файла,

// char m_szFullName[_MAX_PATH] - абсолютное имя файла в Windows

// кодировке (данная функция не заполняет это поле).

// Байт атрибутов файла:

// enum Attribute {

//    normal =     0x00, // обычный

//    readOnly =  0x01, // только для чтения

//    hidden =     0x02, // скрытый

//    system =     0x04, // системный

//    volume =     0x08, // том

//    directory = 0x10, // каталог

//    archive =    0x20   // архивный

//    };

 

virtual CString GetFileName( ) const;

// Возвращает имя файла (с расширением).

 

virtual CString GetFileTitle( ) const;

// Возвращает имя файла (без расширения).

 

virtual CString GetFilePath( ) const;

// Возвращает полный путь к файлу.

 

virtual void SetFilePath( LPCTSTR lpszNewName );

// Устанавливает новый путь для файла (параметр lpszNewName).

// Используется, когда, например, создается объект CFile с помощью

// конструктора по умолчанию.

Примечание:

функция SetFilePath не создает и не открывает файла, она только

ассоциирует имя файла с файловым объектом.

Статические функции

static void PASCAL Rename( LPCTSTR lpszOldName, LPCTSTR lpszNewName );

// Переименовывает указанный файл:

// lpszOldName - старый путь, lpszNewName - новый путь.

// В случае ошибки возбуждается исключительная ситуация.

Примечание:

директории не переименовываются.

static void PASCAL Remove( LPCTSTR lpszFileName );

// Удаляет файл по указанному пути (параметр lpszFileName). Путь

// может быть абсолютным и относительным, но не сетевым.

// В случае ошибки возбуждается исключительная ситуация.

Примечание:

директории не удаляются.

static BOOL PASCAL GetStatus(LPCTSTR lpszFileName, CFileStatus& rStatus);

// lpszFileName - строка в Windows кодировке, содержащая путь к

// указанному файлу. Путь может быть абсолютным и относительным,

// но не сетевым.

// В остальном см. функцию BOOL GetStatus ( CFileStatus& rStatus ) const;

// Отличия:

// данная функция заполняет параметр char m_szFullName[_MAX_PATH] объекта

// структуры CFileStatus,

// данная функция может получить информацию о файле, не открывая его!

 

static void SetStatus( LPCTSTR lpszFileName, const CFileStatus& status );

// Устанавливает новую системную информацию для произвольного файла.

// lpszFileName - содержащая путь к указанному файлу. Путь может быть

// абсолютным и относительным,

// status - объект, содержащий новую системную информацию (если равен

// нулю, то информация не обновляется).

Совет:

вызывайте функцию GetStatus для заполнения полей объекта, а затем

изменить необходимые. Если вы хотите изменить только атрибуты

файла (не изменяя дату и время последней модификации файла,

параметр m_mtime), то сначала установите параметр m_mtime в ноль,

а затем вызывайте функцию SetStatus.

 

CStdioFile

 

Данный класс полностью аналогичен своему родителю классу CFile и, соответственно, имеет возможность вызвать практически любую доступную ему родительскую функцию.

Отличия:

CStdioFile( );               // Конструктор по умолчанию

CStdioFile( FILE* pOpenStream );

// Параметром конструктора служит файловый указатель, полученный

// с помощью C-шной функции fopen.

CStdioFile( LPCTSTR lpszFileName, UINT nOpenFlags );

// см. соответствующий конструктор класса CFile

 

virtual LPTSTR ReadString ( LPTSTR lpsz, UINT nMax );

// Возвращает буфер, содержащий данные, или NULL, если был

// найден конец файла без считывания информации в буфер.

// lpsz - буфер, получающий строку,

// nMax - максимальное количество считываемых символов

// (завершающий ноль (\0) не учитывается).

// Читает либо nMax - 1 символов, либо до символа новой строки.

// Символ новой строки записывается в буфер.

// В конец буфера вставляется завершающий ноль.

// В случае ошибки возбуждается исключительная ситуация.

 

BOOL ReadString( CString& rString);

// Возвращает ложь, если был найден конец файла без считывания

// информации в строку.

// rString - ссылка на объект CString, который будет хранить

// считанные данные.

// rString не хранит символ '\ n'.

// В случае ошибки возбуждается исключительная ситуация.

 

virtual void WriteString( LPCTSTR lpsz );

// Записывает строку lpsz в файл. Символ '\0' в файл не пишется.

// Символ '\n' записывается в файл как пара символов

// конец/перевод строки.

// В случае ошибки возбуждается исключительная ситуация.

 

Заметка:

В данном разделе упоминался класс файловых исключений CFileException. Сейчас мы не будем его подробно рассматривать (он будет применен в практическом примере). Приведем лишь его часть.

Генеалогия

int m_cause;

// открытая (public) переменная, содержащая описание ошибки:

// CFileException::none - ошибок не было,

// CFileException::generic - неизвестная ошибка,

// CFileException::fileNotFound - файл не найден,

// CFileException::badPath - неверный путь,

// CFileException::tooManyOpenFiles - превышено количество

// одновременно открытых файлов,

// CFileException::accessDenied - доступ запрещен,

// CFileException::invalidFile - неверный дескриптор файла,

// CFileException::removeCurrentDir - невозможно удалить

// текущую рабочую директорию,

// CFileException::directoryFull - директория отсутствует,

// CFileException::badSeek - ошибка при перемещении

// файлового указателя,

// CFileException::hardIO - аппаратная ошибка,

// CFileException::sharingViolation - не загружен Share.exe

// или диапазон заблокирован,

// CFileException::lockViolation - попытка повторной блокировки

// заблокированного диапазона,

// CFileException::diskFull - диск переполнен,

// CFileException::endOfFile - достигнут конец файла.
<{{./BAN/ARTIC6}}>