Поиск структур в непрерывном неструктурированном файловом потоке

0

Я пытаюсь вычислить (надеюсь, простой) способ прочитать большой, неструктурированный файл, не нападая на край буфера. Пример здесь полезен.

Представьте, что вы пытаетесь выполнить некоторое восстановление данных с флэш-накопителя на 16 ГБ и сохранили дамп диска в 16-гигабайтный файл. Вы хотите просмотреть изображение, просматривая некоторые интересующие вас объекты. Если файл был меньше, вы могли бы прочитать все это в буфер памяти (скажем, 1 МБ) и выполнить простую проверку через буфер. Однако, поскольку он слишком велик, чтобы читать все сразу, вам нужно прочитать его в кусках. Проблема в том, что интересующий элемент может быть не совсем выровнен, чтобы попасть в один буфер 1 МБ. Другими словами, он может оказаться на краю буфера, чтобы он начинался в конце буфера во время одного чтения и заканчивался в следующем (или даже дальше).

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

Как обычно эта ситуация обрабатывается?

Теги:
stream
unmanaged

1 ответ

0

Если вы работаете в 64-битной среде, я бы просто использовал файлы с отображением памяти. Для процесса нет (разумного) предела памяти. Вы можете прочитать файл, даже прыгать, и ОС будет заменять память на диск и с диска.

Вот некоторые основные сведения:

http://msdn.microsoft.com/en-us/library/ms810613.aspx

И пример средства просмотра файлов здесь:

http://www.catch22.net/tuts/memory-techniques-part-1

Этот случай работает с 2.8GB файлом в x64, но сбой в win32, поскольку он не может выделить более 2 ГБ на процесс. Это очень быстро, так как он касается только первого и последнего байтов в массиве pBuf. Модификация метода для перемещения буфера и подсчета количества "нулевых" байтов работает так, как ожидалось. Вы можете наблюдать, как след памяти растет, как только он делает это, но эта память только фактически распределена.

#include "stdafx.h"
#include <string>
#include <Windows.h>

TCHAR  szName[] = TEXT( pathToFile );

int _tmain(int argc, _TCHAR* argv[])
{
   HANDLE hMapFile;
   char* pBuf;

   HANDLE file = CreateFile( szName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
   if ( file == NULL )
   {
         _tprintf(TEXT("Could not open file object (%d).\n"),
             GetLastError());
      return 1;
   }

   unsigned int length  = GetFileSize(file, 0);

   printf( "Length = %u\n", length );


   hMapFile = CreateFileMapping( file, 0, PAGE_READONLY, 0, 0, 0 );

   if (hMapFile == NULL)
   {
      _tprintf(TEXT("Could not create file mapping object (%d).\n"),  GetLastError());
      return 1;
   }

   pBuf = (char*) MapViewOfFile(hMapFile,  FILE_MAP_READ, 0,0, length);

   if (pBuf == NULL)
   {
      _tprintf(TEXT("Could not map view of file (%d).\n"), GetLastError());

       CloseHandle(hMapFile);

      return 1;
   }

   printf("First Byte: 0x%02x\n", pBuf[0] );
   printf("Last Byte: 0x%02x\n", pBuf[length-1] );
   UnmapViewOfFile(pBuf);

   CloseHandle(hMapFile);

   return 0;
}
  • 0
    Как я уже сказал, я уже пробовал отображенные в памяти файлы. Проблема в том, что даже в 64-битной системе вид карты ограничен, поэтому я не могу отобразить большой файл и вынужден постоянно менять смещение вида и перенастраивать указатели, что ничем не отличается от простого чтение в буфер.
  • 0
    Вы можете иметь несколько представлений файла, отображенного одновременно. При необходимости вы можете отменить отображение и переназначить представления, чтобы создать скользящие окна в данных файла, или изменить размеры представлений, чтобы сделать их меньше / больше. Если вам нужно изучить что-то, что пересекается между двумя представлениями, вы можете просто создать новое представление, которое охватывает диапазон существующих представлений. Когда вы найдете что-то интересное, вы можете сканировать его, используя столько видов, сколько вам нужно, пока не найдете конец элемента. «Я нашел что-то, что могло бы меня заинтересовать, позвольте мне взглянуть на это более широко».
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню