Программирование для Windows NT (том 2)

       

Функция StartConversion


В задачу функции StartConversion входит выбор и открывание исходного файла и файла, в который будет записан результат перекодировки. Когда приложение работает с файлом в режиме отображения на память, открывается только один файл - исходный.

Для выбора файла мы использовали функцию GetOpenFileName, хорошо знакомую вам по предыдущим томам “Библиотеки системного программиста”, посвященным программированию для операционной системы Microsoft Windows версии 3.1.

Выбранные файлы открываются при помощи функции CreateFile. Однако способ открывания зависит от режима работы с файлами. Ниже мы привели фрагмент исходного текста приложения, в котором открывается исходный файл:

#if FILEOP == SYNCHRONOUS_IO

  hSrcFile = CreateFile(ofn.lpstrFile, GENERIC_READ,

    FILE_SHARE_READ, NULL, OPEN_EXISTING,

    FILE_FLAG_SEQUENTIAL_SCAN, NULL);

#elif FILEOP == ASYNCHRONOUS_IO

  hSrcFile = CreateFile(ofn.lpstrFile, GENERIC_READ,

    FILE_SHARE_READ, NULL, OPEN_EXISTING,

    FILE_FLAG_OVERLAPPED, NULL);

#elif FILEOP == MEMORYMAPPED_IO

  hSrcFile = CreateFile(ofn.lpstrFile,

    GENERIC_READ | GENERIC_WRITE,

    0, NULL, OPEN_EXISTING,  0, NULL);

#endif



В синхронном режиме исходный файл будет читаться последовательно, поэтому мы указали режим GENERIC_READ (только чтение) и флаг FILE_FLAG_SEQUENTIAL_SCAN. Так как в процессе перекодировки исходный файл не будет изменяться, нет причин запрещать чтение этого файла для других процессов. Чтобы предоставить доступ другим процессам на чтение исходного файла, мы указали режим совместного использования файла FILE_SHARE_READ.

В асинхронном режиме необходимо указывать флаг FILE_FLAG_OVERLAPPED, что мы и сделали в нашем примере.

Что же касается режима отображения файла на память, то сдесь при открывании файла мы указали режимы GENERIC_READ и GENERIC_WRITE. В результате файл открывается и для чтения, и для записи.

После того как в режиме отображения файла на память исходный файл будет открыт, функция StartConversion вызывает функцию Oem2Char, передавая ей в качестве единственного параметра идентификатор исходного файла:


Oem2Char(hSrcFile);

CloseHandle(hSrcFile);

Функция Oem2Char выполняет перекодировку файла “по месту”. Далее идентификатор исходного файла закрывается функцией CloseHandle, после чего функция StartConversion возвращает управление.

В синхронном и асинхронном режиме функция StartConversion после открывания исходного файла дополнительно открывает выходной файл, в который будет записан результат перекодировки. Для выбора выходного файла вызывается функция GetSaveFileName.

Так же как и исходный файл, выходной файл открывается при помощи функции CreateFile, причем в синхронном и асинхронном режиме этот файл открывается по-разному:

#if FILEOP == SYNCHRONOUS_IO

  hDstFile = CreateFile(ofn.lpstrFile, GENERIC_WRITE,

    0, NULL, CREATE_ALWAYS,

    FILE_FLAG_SEQUENTIAL_SCAN, NULL);

#elif FILEOP == ASYNCHRONOUS_IO

  hDstFile = CreateFile(ofn.lpstrFile, GENERIC_WRITE,

    0, NULL, CREATE_ALWAYS,

    FILE_FLAG_OVERLAPPED,  NULL);

#endif

В синхронном режиме мы указываем режим доступа на запись GENERIC_WRITE и флаг FILE_FLAG_SEQUENTIAL_SCAN (так как запись в выходной файл будет выполняться последовательно от начала до конца).

В асинхронном режиме необходимо указать флаг FILE_FLAG_OVERLAPPED.

Кроме того, в обоих случаях мы указали режим открывания файла CREATE_ALWAYS. В результате выходной файл будет создан заново даже в том случае, если в выбранном каталоге уже есть файл с таким именем. При этом содержимое старого файла будет уничтожено.

После открывания исходного и выходного файла вызывается функция Oem2Char, выполняющая перекодировку, а затем оба файла закрываются при помощи функции CloseHandle:

Oem2Char(hSrcFile, hDstFile);

CloseHandle(hSrcFile);

CloseHandle(hDstFile);

Обратите внимание, что в синхронном и асинхронном режиме работы с файлами в нашем приложении используется другой вариант фукнции Oem2Char - вариант с двумя параметрами. Как вы сейчас увидите, в нашем приложении используются три варианта этой функции.


Содержание раздела