WinAPI. Функции работы с файлами. Часть 2

WinAPI
WinAPI. Функции работы с файлами. Часть 2:

Продолжаем изучать функции API Windows для работы с файлами. Сегодня мы познакомимся функциями для работы с целыми файлами такими как создание, удаление и копирование файлов. Помимо этого будут функции о получении инфы о файлах из системы.

Сегодня ты узнаешь про:

CopyFile

Функция копирует файл в новое место.

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

  BOOL CopyFile(
   LPCTSTR lpExistingFileName,	// Указатель на файл, который надо копировать
   LPCTSTR lpNewFileName,	// Указатель на имя файла, куда надо копировать
   BOOL bFailIfExists 		// Чё делать если файл уже существует.
   );	

  Для Delphi

 function CopyFile(
  lpExistingFileName,    // Указатель на файл, который надо копировать
  lpNewFileName: PChar;  // Указатель на имя файла, куда надо копировать
  bFailIfExists: BOOL    // Чё делать если файл уже существует.
  ): BOOL; stdcall;

Для Delphi есть ещё два варианта этой функции, которые отличаются только типом используемых переменных lpExistingFileName и lpNewFileName:

  function CopyFileA(
    lpExistingFileName, lpNewFileName: PAnsiChar; 
    bFailIfExists: BOOL
    ): BOOL; stdcall;

  function CopyFileW(
    lpExistingFileName, lpNewFileName: PWideChar; 
    bFailIfExists: BOOL
    ): BOOL; stdcall;

Первый и второй параметр содержат полные имена к файлам. Третий параматр указывает, что нужно делать, если файл уже существует. Если он равен TRUE, то произойдёт ошибка, если FALSE, то существующий файл будет перезаписан.

Если всё ничтяк, то функция вернёт TRUE

Пример использования CopyFile('c:\oldfile.exe', 'c:\newfile.exe', false);

CreateDirectory

Функция создаёт новую директорию.

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

   BOOL CreateDirectory(
    LPCTSTR lpPathName, // Указатель на строку содержащую путь к новой директории
    LPSECURITY_ATTRIBUTES lpSecurityAttributes 	// Указатель на атрибуты
   );	

  Для Delphi

   function CreateDirectory(
    lpPathName: PChar; // Указатель на строку содержащую путь к новой директории
    lpSecurityAttributes: PSecurityAttributes // Указатель на атрибуты
    ): BOOL; stdcall;

Для Delphi есть ещё два варианта этой функции, которые отличаются только типом переменной lpPathName:

 function CreateDirectoryA(
   lpPathName: PAnsiChar;
   lpSecurityAttributes: PSecurityAttributes
   ): BOOL; stdcall;

 function CreateDirectoryW(
   lpPathName: PWideChar;
   lpSecurityAttributes: PSecurityAttributes
   ): BOOL; stdcall;

Если всё ничтяк, то функция вернёт TRUE

CreateDirectoryEx

Расширенная функция для создания новой директории. При создании используется указанный шаблон.

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

   BOOL CreateDirectoryEx(
    LPCTSTR lpTemplateDirectory,// Указатель на директорию-шаблон
    LPCTSTR lpPathName, // Указатель на строку содержащую путь к новой директории
    LPSECURITY_ATTRIBUTES lpSecurityAttributes 	// Указатель на атрибуты
   );	

  Для Delphi

   function CreateDirectoryEx(
    lpPathName: PChar; // Указатель на строку содержащую путь к шаблону
    lpPathName: PChar; // Указатель на строку содержащую путь к новой директории
    lpSecurityAttributes: PSecurityAttributes // Указатель на атрибуты
    ): BOOL; stdcall;

Для Delphi есть ещё два варианта этой функции, которые отличаются только типом переменных. Эти функции имеют имена CreateDirectoryExA и CreateDirectoryExW. Я не буду их приводить, просто запомни, что в функциях с буквой А в конце все переменные типа PChar превращаются в AnsiChar, а с префиксом W переменные PChar превращаются в WideString.

Если всё ничтяк, то функция вернёт TRUE

CreateFile

Функция создаёт указатель на новое устройство типа:

  • Файл
  • Канал
  • mailslot (почтовый канал)
  • комуникационный ресурс (например COM порт)
  • дисковые устройства (только для Windows NT)
  • консоли
  • директории (открывает их)

Функция умеет открывать и создавать новые устройства (файлы).

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

   HANDLE CreateFile(
    LPCTSTR lpFileName,	    // Указатель на имя файла (устройства)
    DWORD dwDesiredAccess,  //Параметры доступа
    DWORD dwShareMode,	    //Разделяемый доступ
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,	//безопасность
    DWORD dwCreationDistribution,// Описание
    DWORD dwFlagsAndAttributes,	 // Атрибуты файла
    HANDLE hTemplateFile 	 // Файл шаблона
   );	

  Для Delphi

  function CreateFile(
   lpFileName: PChar;   // Указатель на имя файла (устройства)
   dwDesiredAccess,     //Параметры доступа
   dwShareMode: DWORD;  //Разделяемый доступ
   lpSecurityAttributes: PSecurityAttributes; //безопасность
   dwCreationDisposition,       // Описание
   dwFlagsAndAttributes: DWORD; // Атрибуты файла
   hTemplateFile: THandle       // Файл шаблона
   ): THandle; stdcall;

Для Delphi есть ещё два варианта этой функции, которые отличаются только типом переменных. Эти функции имеют имена CreateFileA и CreateFileW. Я не буду их приводить, просто запомни, что в функциях с буквой А вконце все переменные типа PChar превращаются в AnsiChar, а с префиксом W переменные PChar превращаются в WideString.

В принципе, практически для всех API функций в Delphi доступно два дополнительных варианта, в которых действует описанное выше правило. Так что я больше не буду к этому возвращаться.

В С/С++ тоже есть три варианта, но различие в имени там бывает редко. Поэтому я даже не заикался об этом.

Теперь рассмотрим подробненько все параметры:

  • lpFileName - Указатель на строку содержащую имя создаваемого файла или устройства.
  • dwDesiredAccess - тип доступа. Может принимать значения (можно использовать одно или сразу несколько):
    • 0 - запрос. Функция не даст реального доступа к файлу, а выполнится как тест возможности создания или открытия файла (устройства).
    • GENERIC_READ - получить доступ к чтению
    • GENERIC_WRITE - получить доступ к записи
  • dwShareMode - флаги, указывающие на то, как создаваемый (открываемый) объект должен разделять достум между процессами. Это значит, как будет делится доступ к файлу с другими прогами если они тоже попытаются открыть этот файл. Параметр может принимать значения (можно использовать одно или сразу несколько):
    • FILE_SHARE_DELETE - другим процессам разрешается доступ к файла (устройству) только если требуется доступ на удаление (поддерживается только в Windows NT).
    • FILE_SHARE_READ - другим процессам разрешается только читать файл
    • FILE_SHARE_WRITE - другим процессам разрешается только писать в файл
  • lpSecurityAttributes - указатель на структуру типа SECURITY_ATTRIBUTES. Этот параметр используется только в Windows NT, в Win9x он игнорируется.
  • dwCreationDistribution - описывает, что делать с файлом если он уже существует или его ещё нет. Параметр может принимать только одно из следующих значений (комбинация не допускается):
    • CREATE_NEW - создать новый файл. Если он уже существует, то произойдёт ошибка
    • CREATE_ALWAYS - а я сказал создать новый файл. Если файл существует, то он будет перезаписан (обнулён).
    • OPEN_EXISTING - открыть существующий файл (устройство). Если файла нет, то произойдёт ошибка.
    • OPEN_ALWAYS - а я сказал открыть файл. Если файла нет, то он будет создан как при использовании CREATE_NEW.
    • TRUNCATE_EXISTING - открыть файл и обрезать его размер до нуля. Параметр dwDesiredAccess должен содержать GENERIC_WRITE. Если файла нет, то произойдёт ошибка.
  • dwFlagsAndAttributes - атрибуты создаваемого файла. Параметр может принимать комбинацию из значений:
    • FILE_ATTRIBUTE_NORMAL
      • FILE_ATTRIBUTE_ARCHIVE - архивный
      • FILE_ATTRIBUTE_COMPRESSED - сжатый
      • FILE_ATTRIBUTE_HIDDEN - скрытый
      • FILE_ATTRIBUTE_NORMAL - нормальный
      • FILE_ATTRIBUTE_OFFLINE - данные файла недоступны
      • FILE_ATTRIBUTE_READONLY - только для чтения
      • FILE_ATTRIBUTE_SYSTEM - системный
      • FILE_ATTRIBUTE_TEMPORARY - временный
    • FILE_FLAG_WRITE_THROUGH - возможность записи в файл через кэш.
    • FILE_FLAG_NO_BUFFERING - нельзя использовать буферы или кэш
    • FILE_FLAG_RANDOM_ACCESS - случайный доступ. Используется для оптимизации кэша
    • FILE_FLAG_SEQUENTIAL_SCAN - доступ к файлу может быть последовательный от начала до конца
    • FILE_FLAG_DELETE_ON_CLOSE - операционная система должна удалить файл, когда все указатели на файл будут закрыты
    • FILE_FLAG_BACKUP_SEMANTICS - Backup файл, т.е. файл резервного копирования.
    • FILE_FLAG_POSIX_SEMANTICS - доступ осуществляется в POSIX стандарте.
    • SECURITY_SQOS_PRESENT
      • SECURITY_ANONYMOUS - анонимный доступ
      • SECURITY_IDENTIFICATION - идентификационный доступ
      • SECURITY_IMPERSONATION - персональный доступ
      • SECURITY_DELEGATION - колективный доступ
      • SECURITY_CONTEXT_TRACKING - динамический режим доступа
      • SECURITY_EFFECTIVE_ONLY - ограничение груп и привелегий
  • hTemplateFile - файл шаблона

Если функция выполнилась без проблем, то она возвращает указатель на открытое (созданное) устройства. Через этот указатель ты получаешь доступ к файлу.

Если произошла ошибка, то функция вернёт INVALID_HANDLE_VALUE.

DeleteFile

Функция удаления существующего файла

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

  BOOL DeleteFile(
    LPCTSTR lpFileName 	// Указатель на строку с полным именем файла
   );	

  Для Delphi

  function DeleteFile(
   lpFileName: PChar// Указатель на строку с полным именем файла
  ): BOOL; stdcall;

Если всё ничтяк, то функция вернёт TRUE

FindFirstFile

Функция запускает поиск файла в указанной директории.

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

   HANDLE FindFirstFile(
    LPCTSTR lpFileName,	// Строка содержащая путь для поиска файлов.
    LPWIN32_FIND_DATA lpFindFileData // Информация о файле
   );

  Для Delphi

  function FindFirstFile(
   lpFileName: PChar; // Строка содержащая путь для поиска файлов.
   var lpFindFileData: TWIN32FindData // Информация о файле
  ): THandle; stdcall;

Здесь стоит посмотреть на оба параметра подробнее:

  • lpFileName - строка содержащая путь для поиска файла. Эта строка может указывать на конкретный файл типа 'c:\filename.txt' или может хранить шаблон 'c:\*.txt'. Если ты указываешь шаблон, то это даёт возможность перечислить все файлы удовлетворяющие шаблону.
  • lpFindFileData - структура WIN32_FIND_DATA, в которую будет записана инфа о найденном файле.

Расмотрим структуру WIN32_FIND_DATA немного подробнее:

  typedef struct _WIN32_FIND_DATA { 
    DWORD dwFileAttributes;  // Атрибуты файла
    FILETIME ftCreationTime; // Время создания
    FILETIME ftLastAccessTime;  //Время последнего доступа
    FILETIME ftLastWriteTime;   //Время последней записи в файл
    DWORD    nFileSizeHigh;     //Верхний байт размера файла
    DWORD    nFileSizeLow;      //Нижний байт размера файла
    DWORD    dwReserved0;       //Зарезервировано
    DWORD    dwReserved1;       //Зарезервировано
    TCHAR    cFileName[ MAX_PATH ];    //Имя файла
    TCHAR    cAlternateFileName[ 14 ]; //Имя файла для отображения в DOS (8:3)
  } WIN32_FIND_DATA; 

Атрибутами файла может быть комбинация из флагов:

  • FILE_ATTRIBUTE_ARCHIVE - архивный
  • FILE_ATTRIBUTE_COMPRESSED - сжатый
  • FILE_ATTRIBUTE_HIDDEN - скрытый
  • FILE_ATTRIBUTE_NORMAL - нормальный
  • FILE_ATTRIBUTE_OFFLINE - данные файла недоступны
  • FILE_ATTRIBUTE_READONLY - только для чтения
  • FILE_ATTRIBUTE_SYSTEM - системный
  • FILE_ATTRIBUTE_TEMPORARY - временный

Размер файла разложен на два байта. Чтоб получить полный размер файла нужно выполнить действие (FInfo.nFileSizeHigh * MAXDWORD) + FInfo.nFileSizeLow. Это не самый эффективный (эффективнее сдвигать), но самый понятный способ.

Функция возвращает указатель на найденный файл, если нет то возврат будет типа ERROR_NO_MORE_FILES.

FindNextFile

Функция продолжает поиск начатый с помощью FindFirstFile.

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

  BOOL FindNextFile(
    HANDLE hFindFile,	// Указатель на файл из предыдущего поиска
    LPWIN32_FIND_DATA lpFindFileData // Информация о файле
   );	

  Для Delphi

  function FindNextFile(
    hFindFile: THandle; // Указатель на файл из предыдущего поиска
    var lpFindFileData: TWIN32FindData // Информация о файле
   ): BOOL; stdcall;

Со вторым параметром всё ясно, он такой же, как и у FindFirstFile. А вот первый - это указатель на файл из предыдущего поиска. Он нужен, чтобы функция FindNextFile знала на каком файле ты остановил поиск и какой надо найти следующим. Немного позже мы рассмотрим реальный пример, чтобы тебе стало понятнее.

Если всё ничтяк, то функция вернёт TRUE

FindClose

Функция завершает поиск файлов.

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

  BOOL FindClose(
    HANDLE hFindFile 	// Указатель на последний найденный файл
   );	

  Для Delphi

  function FindClose(
    hFindFile: THandle  // Указатель на последний найденный файл
   ): BOOL; stdcall;

Если всё ничтяк, то функция вернёт TRUE

Пример для FindFirstFile, FindNextFile, FindClose

var
 FileName: string;
 FindHandle:THandle;
 SearchRec:TWIN32FindData;
begin
 try
  FindHandle := FindFirstFile('c:\*.*', SearchRec);
  if SearchRec.FindHandle <> INVALID_HANDLE_VALUE then
  repeat
   FileName:=SearchRec.cFileName
  until FindNextFile(FindHandle,SearchRec)=false;
  finally
   Windows.FindClose(FindHandle);
  end;
end;

GetCurrentDirectory

Функция позволяет узнать текущую директорию, с которой сейчас работает твоя прога.

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

   DWORD GetCurrentDirectory(
    DWORD nBufferLength, // Размер буфера, в котором будет храниться путь
    LPTSTR lpBuffer 	 // Сам буфер
   );	

  Для Delphi

   function GetCurrentDirectory(
    nBufferLength: DWORD; // Размер буфера, в котором будет храниться путь
    lpBuffer: PChar       // Сам буфер
    ): DWORD; stdcall;

Если произошла ошибка, то функция вернёт 0. Если всё ничтяк, то она вернёт длину lpBuffer в котором хранится путь текущей директории.

SetCurrentDirectory

Функция позволяет узнать текущую директорию, с которой сейчас работает твоя прога.

Существует в: Win16, Win32, Win NT

Для С/С++ объявлена в winbase.h. Для Delphi в модуле windows.

Объявление:

  Для С/С++

   BOOL SetCurrentDirectory(
    LPCTSTR lpPathName 	// Новая диретория
   );	

  Для Delphi

  function SetCurrentDirectory(
   lpPathName: PChar   // Новая диретория
  ): BOOL; stdcall;

Если произошла ошибка, то функция вернёт 0. Если всё ничтяк, то она вернёт не ноль.

Ну всё, на сегодня хватит. Я и так уже накатал 20 кило инфы. В следующий раз продолжим.



Опубликовал admin
28 Май, Среда 2003г.



Программирование для чайников.