• Программа использует первое поле в качестве ключа, но определяет его длину.
• Строятся два представления файла. Одно из них представляет исходный файл, а второе — файл, содержащий отсортированные ключи. Второй файл является
• Индексный файл сохраняется и впоследствии может быть использован, причем предусмотрена возможность (параметр командной строки –I) отказаться от сортировки и использовать существующий индексный файл. Кроме того, индексный файл может быть использован для быстрого поиска ключей путем проведения бинарного поиска (возможно, с использованием входящей в библиотеку C функции bsearch) в индексном файле.
Взаимосвязь между индексным файлом и сортируемым файлом иллюстрирует рис. 5.5. Главной программой является программа 5.5, которая обеспечивает создание представлений файлов в памяти компьютера, осуществляет сортировку индексного файла и отображает результаты. Эта программа вызывает функцию CreateIndexFile, представленную программой 5.6.
Рис. 5.5. Сортировка с использованием отображения индексного файла
/* Глава 5. Команда sortMM.
Сортировка отображенного в памяти файла – только один файл. Опции:
-r Сортировать в обратном порядке.
-I Использовать индексный файл для получения отсортированного файла. */
#include "EvryThng.h"
int KeyCompare(LPCTSTR , LPCTSTR);
DWORD CreateIndexFile (DWORD, LPCTSTR, LPTSTR);
DWORD KStart, KSize; /* Начальная позиция и размер ключа (TCHAR) . */
BOOL Revrs;
int _tmain(int argc, LPTSTR argv []) {
HANDLE hInFile, hInMap; /* Дескрипторы входного файла. */
HANDLE hXFile, hXMap; /* Дескрипторы индексного файла. */
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
BOOL IdxExists;
DWORD FsIn, FsX, RSize, iKey, nWrite, *pSizes;
LPTSTR pInFile = NULL;
LPBYTE pXFile = NULL, pX;
TCHAR _based(pInFile) *pIn;
TCHAR IdxFlNam [MAX_PATH], ChNewLine = TNEWLINE;
int FlIdx = Options(argc, argv, _T("rI"), &Revrs, &IdxExists, NULL);
/* Шаг 1: открыть и отобразить входной файл. */
hInFile = CreateFile(argv [FlIdx], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
hInMap = CreateFileMapping(hInFile, NULL, PAGE_READWRITE, 0, 0, NULL);
pInFile = MapViewOfFile(hInMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
FsIn = GetFileSize(hInFile, NULL);
/* Шаги 2 и З: создать имя индексного файла. */
_stprintf(IdxFlNam, _T("%s%s"), argv[FlIdx], _T(".idx"));
if (!IdxExists) RSize = CreateIndexFile(FsIn, IdxFlNam, pInFile);
/* Шаг 4: отобразить индексный файл. */
hXFile = CreateFile(IdxFlNam, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
hXMap = CreateFileMapping(hXFile, NULL, PAGE_READWRITE, 0, 0, NULL);
pXFile = MapViewOfFile(hXMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
FsX = GetFileSize(hXFile, NULL);
pSizes = (LPDWORD)pXFile; /* Поля размера в .idx-файле. */
KSize = *pSizes; /* Размер ключа */
KStart = *(pSizes + 1); /* Начальная позиция ключа в записи. */
FsX –= 2 * sizeof(DWORD);