Шаг 8.
Технология OLE. Фрагментация составных файлов

    На этом шаге мы приведем функцию, осуществляющую фрагментацию составных файлов.

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

    Существуют процедуры, дефрагментирующие составные файлы

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

    Листинг 1. Процедура дефрагментации составных файлов

void CompressCompoundFile(char * szFile)
{
  // Дано: szFile содержит имя файла, который необходимо дефрагментировать.
  // Объявление нескольких рабочих переменных.
  LPSTORAGE pINew; // Указатель на интерфейс IStorage.
  LPSTORAGE pIOld; // Указатель на интерфейс IStorage.
  LPMALLOC pIMalloc; // Указатель на интерфейс IMalloc.
  STATSTG StorageStatus;  // Структура STATSTG. 
  HRESULT hResult;  // Дескриптор результата.
  char szError[129];  // Участок памяти для сообщений об ошибках.
  //Инициализация перед работой: 
  hResult = CoGetMalloc(MEMCTX_TASK,  &pIMalloc); 
  if (FAILED(hResult))
  {// Нельзя получить дескриптор функции выделения памяти: 
    return;
  }
  // Сначала проверим,  действительно ли это составной файл: 
  if (FAILED(StgIsStorageFile(szFile))) {// Это не составной файл!
    wsprintf(szError, "File %s is not a compound file.",  szFile);
    MessageBox(szError,   "Compound file compressor",  MB_OK);
    pIMalloc->Release();
    return;
  }
  // Теперь мы знаем,   что имеем дело с составным файлом. 
  // Сначала откроем новый файл для записи: 
  hResult = StgCreateDocfile(NULL,  STGM_CREATE | STGM_READWRITE  |  
    STGM_DIRECT  |  STGM_SHARE_EXCLUSIVE,   0,  &pINew); 
  if (FAILED(hResult)) {// Нельзя открыть новый составной файл...
    wsprintf(szError, "Temporary file could not be opened.");
    MessageBox(szError,   "Compound file compressor",  MB_OK);
    pIMalloc->Release();
    return;
  }
  // Затем откроем старый файл: 
  hResult = StgOpenDocfile(szFile, STGMREAD  |  STGM_DIRECT  |  
    STGM_SHARE_EXCLUSIVE, NULL, 0, &pIOld); 
  if (FAILED(hResult)) {// Нельзя открыть настоящий составной файл...
    wsprintf(szError,   "Original file %s could not be opened, ", szFile);
    MessageBox(szError,   "Compound file compressor",  MB_OK);
    pINew->Release();
    pIMalloc->Release();
    return;
  }
  hResult = pIOld->CopyTo(NULL,   NULL,   NULL,   pINew);
  pIOld->Release():
  if (FAILED(hResult))
  {// Нельзя скопировать файл...
    wsprintf(szError, "Original file %s could not be copied.", szFile);
    MessageBox(szError, "Compound file compressor", MB_OK);
    pINew->Release();
    pIMalloc->Release();
    return;
  }

  // Теперь pINew - дефрагментированная копия pIOld.
  // Далее, скопируем его назад в pIOld: 
  hResult = StgCreateDocfile(szFile, STGM_CREATE | STGM_WRITE | 
    STGM_DIRECT | STGM_SHARE_EXCLUSIVE, NULL, 0, &pIOld);
   if (FAILED(hResult)) {// Нельзя открыть заново старый составной файл.
    pINew->Stat(&StorageStatus, 0);
    pINew->Release();
    wsprintf(szError, "Cannot overwrite file %s, new copy is named named", 
        szFile, st.pwcsName);
    MessageBox(szError, "Compound file compressor", MB_OK);
    pIMalloc->Free((LPVOID) st.pwcsName);
    pIMalloc->Release();
    return;
  }
  // Все в порядке, новый составной файл скопирован поверх старого.
  // Удалим теперь временный файл...
  pINew->CopyTo(NULL, NULL, NULL, pIOld);
  pIOld->Release();
  pINew->Stat(&StorageStatus, 0);
  pINew->Release();
  OpenFile(StorageStatus.pwcsName, &OpenFileStruct, OF_DELETE);
  pIMalloc->Free((LPVOID) st.pwcsName);
  pIMalloc->Release();
  return;
}

    Предыдущий код - в действительности нечто большее, чем простая дефрагментация составного файла: это также пример выполнения операций над составным файлом.

    На следующем шаге мы рассмотрим интерфейсы памяти .




Предыдущий шаг Содержание Следующий шаг