Сообщений 0 Оценка 16 Оценить |
Рассмотрение начнем с системных функций Windows. Сразу необходимо напомнить, что имея дело с файлами, всегда необходимо помнить об ограничении длины полного имени файла, накладываемого операционной системой. Для ANSI-версий функций (единственно доступных для ОС Windows 95/98), выполняющих файловые операции, максимальная длина буфера, содержащего полный путь к файлу (включая ноль-терминатор) равна MAX_PATH (что составляет 260 для PC-архитектуры и 256 для MAC). Для Windows NT/2000 доступны UNICODE-версии функций, которые способны "расширить этот предел вплоть до 32 000 широких символов" (цитировалось дословно по MSDN; точное число символов, скрывающееся за формулировкой "вплоть до 32 000" мне не известно). В последнем случае UNICODE-строка, содержащая полный путь к файлу, должна начинаться символами "\\?\". Для более полной информации см. раздел "File Name Conventions" в MSDN.
Копирование файла выполняет функция CopyFile( ), при этом она позволяет настраивать поведение в зависимости от того, существует или нет целевой файл toName.
BOOL WINAPI CopyFile(LPCTSTR fromName, LPCTSTR toName, BOOL failIfExists); |
Если failIfExists установлен в TRUE, то при условии, что файл с именем toName уже существует, то функция завершится ошибкой. В противном случае (failIfExists = FALSE) имеющийся файл toName будет перезаписан.
Перемещение и переименование файла с точки зрения файловой системы не имеет отличий, поскольку и в первом, и во втором случае изменяется полное имя файла. Эту операцию можно выполнить функцией MoveFile( ).
BOOL WINAPI MoveFile(LPCTSTR fromName, LPCTSTR toName); |
Функция MoveFile имеет ряд ограничений. Во-первых, она не позволяет обработать ситуацию, когда уже имеется файл с именем toName. Второе ограничение связано с тем, что функция MoveFile( ) способна перемещать не только файлы, но и каталоги. Так вот перемещение каталога должно происходить в пределах одного тома.
Для преодоления указанных ограничений имеется функция MoveFileEx( ).
BOOL WINAPI MoveFileEx(LPCTSTR fromName, LPCTSTR toName, DWORD dwFlags); |
Чтобы при перемещении файла можно было перезаписать имеющийся уже файл с именем toName, необходимо установить флаг MOVEFILE_REPLACE_EXISTING. Для перемещения каталога на другой том необходимо установить флаг MOVEFILE_COPY_ALLOWED.
Удаление файла может быть выполнено функцией DeleteFile( ).
BOOL WINAPI DeleteFile(LPCTSTR fileName); |
ПРЕДУПРЕЖДЕНИЕ Указанная функция при работе под Windows95 способна удалить и открытый файл, и файл, отображенный в память. Авторы MSDN рекомендуют закрыть файл перед тем как попытаться удалить его. |
Все упомянутые функции при длительных операциях возвращают управление в программу только по окончании операции с файлом. Иногда это неудобно. Тогда вам может помочь функция SHFileOperation, которая позволяет визуализировать процесс выполнения файловой операции.
// #include <windows.h> // #pragma comment(lib,"shell32") int SHFileOperation(LPSHFILEOPSTRUCT lpFileOp); |
Параметры файловой операции задаются установкой значений структуры SHFILEOPSTRUCT, указатель на которую передается функции.
typedef struct _SHFILEOPSTRUCT{ HWND hwnd; // хэндл окна-владельца диалога UINT wFunc; // тип файловой операции LPCTSTR pFrom; // путь-источник LPCTSTR pTo; // путь-назначение FILEOP_FLAGS fFlags; // флаги операции BOOL fAnyOperationsAborted; // признак прерванной операции LPVOID hNameMappings; LPCSTR lpszProgressTitle; // заголовок диалога } SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT; |
Тип файловой операции задается полем wFunc и может принимать значения FO_COPY, FO_DELETE, FO_MOVE и FO_RENAME. Поле fFlags может содержать большое количество разнообразных флагов, изменяющихся в зависимости от типа выполняемой операции и необходимого поведения функции. Так флаг FOF_SILENT позволяет подавить вывод диалога, отображающего выполнение файловой операции во времени (прогресс-диалога), флаг FOF_NOCONFIRMATION подавляет вывод запросов на подтверждение выполнения файловой операции, флаг FOF_NOCONFIRMMKDIR подавляет вывод запросов на подтверждение создания каталогов во время выполнения копирования и перемещения каталогов, флаг FOF_NOERRORUI подавляет вывод сообщений об ошибках, возникших во время выполнения операции, флаг FOF_NORECURSION позволяет выполнить операцию только с содержимым указанного каталога, флаг FOF_SIMPLEPROGRESS позволяет отображение прогресс-диалога без вывода имен файлов и каталогов, с которыми производится операция (пример применения функции SHFileOperation( ) см. в статье "Как программно удалить каталог со всеми файлами и подкаталогами?").
Кроме того, функция SHFileOperation( ) позволяет выполнить удаление файла в "Корзину". Для этого необходимо к набору флагов добавить флаг FOF_ALLOWUNDO и обязательно указать полный путь к файлу в поле pFrom.
Теперь, после рассмотрения системных функций, выполняющих операции с файлами, можно напомнить, что программистам на языках C/C++ иногда более привычно использовать функции библиотеки времени исполнения (так называемый "рантайм").
Копирование файла средствами рантайм-библиотеки возможно лишь при помощи открытия файла-источника и файла-приемника и непосредственным копированием содержимого из одного в другой.
#include <stdio.h> #include <fcntl.h> #include <io.h> #define BUF_SIZE 1024 int src, dst, size; char buf[BUF_SIZE]; src = _open(sourceFile, _O_BINARY | _O_RDONLY); dst = _open(destFile, _O_BINARY | _O_CREAT | _O_TRUNC | _O_WRONLY); while(!_eof(src)) { if( ( size = _read( src, buf, BUF_SIZE ) ) == -1 ) { perror("Read error\n"); break; } if( _write( dst, buf, size ) == -1 ) { perror("Write error\n"); break; } } _close(dst); _close(src); |
Удаление файла средствами рантайм-библиотеки возможно при помощи функции remove( ) (или _unlink( )).
#include <stdio.h> int err = remove(szFileToDelete); |
Перемещение/переименование файла в рантайм-библиотеке выполняет функция rename( ):
#include <stdio.h> #include <io.h> int err = 0; if(!_access( szToName, 0 )) err = _unlink( szToName ); if(!err) err = rename( szFromName, szToName ); |
Функция rename( ) имеет ограничения - файл szToName не должен существовать. Поэтому сначала необходимо выяснить, существует такой файл или нет, и, в случае, если существует, предварительно удалить его.
В заключение необходимо заметить, что данная статья выполняет лишь роль обзорно-ознакомительной, и ни в коей мере не может считаться полноценным руководством по файловым операциям в среде Windows.
Сообщений 0 Оценка 16 Оценить |