KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программирование » Джонсон Харт - Системное программирование в среде Windows

Джонсон Харт - Системное программирование в среде Windows

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Джонсон Харт, "Системное программирование в среде Windows" бесплатно, без регистрации.
Перейти на страницу:

  CatFile (hInFile, hStdOut);

  CloseHandle (hInFile);

 }

 return 0;

}


/* Функция, выполняющая всю работу:

/* читает входные данные и копирует их на стандартное устройства вывода. */

static VOID CatFile(HANDLE hInFile, HANDLE hOutFile) {

 DWORD nIn, nOut;

 BYTE Buffer [BUF_SIZE];

 while (ReadFile(hInFile, Buffer, BUF_SIZE, &nIn, NULL) && (nIn != 0) && WriteFile(hOutFile, Buffer, nIn, &nOut, NULL));

 return;

}

Пример: преобразование символов из ASCII в Unicode

Программа 2.4 достраивает программу 1.3, в которой использовалась вспомогательная функция CopyFile. С копированием файлов вы уже знакомы, поэтому в данном примере эта операция дополняется преобразованием файла к кодировке Unicode в предположении, что первоначальной кодировкой символов является ASCII, хотя проверка этого предположения не производится. В программе предусмотрены некоторые возможности вывода сообщений об ошибках и параметр, позволяющий подавить замену существующего файла; завершающий вызов функции CopyFile заменен в программе вызовом новой функции, которая Выполняет преобразование символьных строк файла из кодировки ASCII в кодировку Unicode.

В данной программе основное внимание уделяется обеспечению возможности успешного завершения преобразования. Фактическое выполнение преобразования сосредоточено в единственной функции, вызываемой в самом конце программы. Этот фрагмент, как и аналогичный ему фрагмент предыдущей программы, послужит нам шаблоном и будет вновь использоваться в последующих программах без повторения его исходного кода.

Обратите внимание на вызов функции _taccess, проверяющей существование файла. Эта функция является обобщенной версией функции access, которая имеется в библиотеке UNIX, но не входит в состав стандартной библиотеки С. Ее определение содержится в файле <io.h>. Если говорить точнее, функция _taccess осуществляет проверку прав доступа к файлу в соответствии с режимом, установленным значением второго параметра. Значение 0 задает проверку существования файла, 2 — проверку наличия разрешения на запись в файл, 4 — проверку наличия разрешения на чтение из файла, 6 — проверку наличия разрешения как на чтение из файла, так и на запись в файл (эти значения не связаны напрямую с такими параметрами доступа, используемыми в Windows, как GENERIC_READ). Альтернативой проверке существования файла могло бы быть открытие дескриптора при помощи функции CreateFile и его последующее закрытие после проверки действительности дескриптора. 

Программа 2.4. atou: преобразование файла с выводом сообщений об ошибках 

/* Глава 2. atou – копирование файлов с преобразованием из ASCII в Unicode. */

#include "EvryThng.h"


BOOL Asc2Un(LPCTSTR, LPCTSTR, BOOL);

int _tmain(int argc, LPTSTR argv[]) {

 DWORD LocFileIn, LocFileOut;

 BOOL DashI = FALSE;

 TCHAR YNResp[3] = _T("y");

 /* Получить параметры командной строки и индекс входного файла. */

 LocFileIn = Options(argc, argv, _T("i"), &DashI, NULL);

 LocFileOut = LocFileIn + 1;

 if (DashI) { /* Существует ли выходной файл? */

  /* Обобщенная версия функции access, осуществляющая проверку существования файла. */

  if (_taccess(argv[LocFileOut], 0) == 0) {

   _tprintf(_T("Перезаписать существующий файл? [y/n]"));

   _tscanf(_T ("%s"), &YNResp);

   if (lstrcmp(CharLower(YNResp), YES) != 0) ReportError(_T("Отказ от перезаписи"), 4, FALSE);

  }

 }

 /* Эта функция построена на основе функции CopyFile. */

 Asc2Un(argv[LocFileIn], argv [LocFileOut], FALSE);

 return 0;

}

Программа 2.5 — это вызываемая в программе 2.4 функция Asc2Un, осуществляющая преобразование кодировки символов.

Программа 2.5. Функция Asc2Un

#include "EvryThng.h"

#define BUF_SIZE 256


BOOL Asc2Un(LPCTSTR fIn, LPCTSTR fOut, BOOL bFailIfExists)

/* Функция копирования файлов с преобразованием из ASCII в Unicode. Функция построена на основе функции CopyFile. */

{

 HANDLE hIn, hOut;

 DWORD dwOut, nIn, nOut, iCopy;

 CHAR aBuffer[BUF_SIZE];

 WCHAR uBuffer [BUF_SIZE];

 BOOL WriteOK = TRUE;

 hIn = CreateFile(fin, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 

 /* Определить поведение функции CreateFile, если выходной файл уже существует. */

 dwOut = bFailIfExists ? CREATE_NEW : CREATE_ALWAYS;

 hOut = CreateFile(fOut, GENERIC_WRITE, 0, NULL, dwOut, FILE_ATTRIBUTE_NORMAL, NULL);

 while (ReadFile(hIn, aBuffer, BUF_SIZE, &nIn, NULL)  && nIn > 0 && WriteOK) {

  for (iCopy = 0; iCopy < nIn; iCopy++)

   /* Преобразовать каждый символ. */

   uBuffer[iCopy] = (WCHAR)aBuffer [iCopy];

  WriteOK = WriteFile(hOut, uBuffer, 2 * nIn, &nOut, NULL);

 }

 CloseHandle(hIn);

 CloseHandle(hOut);

 return WriteOK;

}

Производительность программы

Как показано в приложении В, производительность программы преобразования файлов можно повысить, предоставив буфер большего размера и задав флаг FILE_FLAG_SEQUENTIAL_SCAN при вызове функции CreateFile. В приложении В также сравниваются показатели производительности программы для файловых систем NTFS и распределенных файловых систем.

Управление файлами и каталогами

В этом разделе вводятся основные функции, предназначенные для управления файлами и каталогами.

Управление файлами

Для управления файлами Windows предоставляет целый ряд функций, работа с которыми обычно не представляет сложности. Ниже описаны функции, с помощью которых можно удалять, копировать и переименовывать файлы. Существует также функция, предназначенная для создания имен временных файлов.

При удалении файла достаточно указать его имя. Вспомните, что все полные имена файлов начинаются с буквы диска или имени сервера. Открытый файл, вообще говоря, удалить невозможно (это допускается в Windows 9x и UNIX); попытка выполнения подобной операции закончится неудачей. У такого ограничения есть свои положительные стороны, поскольку оно предотвращает случайное удаление открытых файлов. 

BOOL DeleteFile(LPCTSTR lpFileName) 

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

BOOL CopyFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL fFailIfExists) 

Функция CopyFile копирует существующий файл с заданным именем и присваивает копии указанное новое имя. В случае существования файла с таким же именем он будет заменен новым файлом только в том случае, если значением параметра fFailIfExists является FALSE.

Под управлением NT5 можно создать жесткую ссылку (hard link) для двух файлов, аналогичную жестким ссылкам в UNIX, используя для этого функцию CreateHardLink. Жесткие ссылки делают возможным существование файла под двумя различными именами. Заметьте, что в подобных случаях файл как таковой существует в единственном числе, и поэтому можно произвольно использовать любое из его имен, независимо от того, какое из них было использовано для открытия файла.

BOOL CreateHardLink(LPCTSTR lpFileName, LPCTSTR lpExistingFileName, BOOL lpSecurityAttributes) 

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

Если заглянуть в документацию Microsoft, то можно увидеть, что в структуре BY_HANDLE_FILE_INFO имеется поле "количество ссылок", и именно этот счетчик используется для определения того, может или не может быть удален данный файл. Функция DeleteFile удаляет имя из каталога файловой системы, но сам файл не может быть удален до тех пор, пока значение счетчика "количество ссылок" не станет равным 0.

Гибких ссылок (soft link) в Windows не существует, хотя оболочки Windows (но не сама Windows), руководствующиеся при определении местоположения файла его содержимым, поддерживают ярлыки (shortcuts). Ярлыки предоставляют средства, подобные гибким ссылкам, но воспользоваться ими могут только пользователи оболочки.

Доступны две функции, позволяющие переименовывать, или "перемещать", файл. Эти же функции применимы и к каталогам. (Функции DeleteFile и CopyFile могут применяться только к файлам.) 

BOOL MoveFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName)

BOOL MoveFileEx(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, DWORD dwFlags) 

Если новый файл уже существует, функция MoveFile завершается с ошибкой; в этом случае следует использовать функцию MoveFileEx. Заметьте, что суффикс "Ех" обычно применяется для обозначения усовершенствованных версий функций, обладающих расширенными (extended) функциональными возможностями.

Параметры

lpExistingFileName — указатель на строку, содержащую имя существующего файла или каталога.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*