2015-03-02 3 views
0

В настоящее время я пытаюсь переписать Binary Diff для поддержки больших файлов, так как использование GetMem для чтения файлов ограничивает размер файла (я полагаю), и я не умею читать 2 файла с размером 900 МБ каждый.VirtualAlloc - выделение пространства для больших файлов

Итак, я понял, что мог бы использовать VirtualAlloc, который, к сожалению, так хорошо не работал. Выделение для первого файла прекрасно работает из его взглядов - как только я пытаюсь выделить память для второго файла, он возвращает нулевой указатель. Должен сказать, что я довольно новичок в распределении памяти, так что простите меня, если бы я мог контролировать поток, который уже отвечает на этот вопрос (я искал интернет для решения за последние 4 часа).

Ну, Херес код:

procedure TFileData.LoadFile; 
var 
    FileHandle: Integer; 
    BytesRead: Integer; 
    dataPoint : Pointer; 
begin 
    FileHandle := FileOpen(fName, fmOpenRead or fmShareDenyWrite); 
    try 
    if FileHandle = -1 then 
     Error('Cannot open file %s', [fName]); 
    fSize := GetFileSize(FileHandle, nil); 
    if fSize = Cardinal(-1) then 
     Error('Cannot find size of file %s - may be to large', [fName]); 
    if fSize = 0 then 
     Error('File %s is empty', [fName]); 
    try 

     dataPoint := VirtualAlloc(nil,fSize,MEM_COMMIT,PAGE_READWRITE); 
     fData := dataPoint; 
     BytesRead := FileRead(FileHandle, fData^, fSize); 
     if BytesRead = -1 then 
      Error('Cannot read from file %s', [fName]); 
     if fSize <> Cardinal(BytesRead) then 
      Error('Error reading from file %s', [fName]); 
    except 
     if Assigned(fData) then 
     FreeMem(fData, fSize); 
     raise; 
    end; 
    finally 
    if FileHandle <> -1 then 
     FileClose(FileHandle); 
    end; 
end; 

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

+2

Попробуйте [файлы с отображением памяти] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa366556%28v=vs.85%29.aspx). –

+0

Спасибо, я сделаю снимок. – trsx

+0

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

ответ

4

VirtualAlloc не поможет. Ваш вызов GetMem для такого большого блока памяти будет реализован как вызов VirtualAlloc. Конечно, это не помогает, что ваш код VirtualAlloc ошибочен. Совпадение VirtualAlloc с FreeMem действительно не очень хорошее. Однако, поскольку VirtualAlloc не является ответом, я не буду останавливаться на этом.

Ваша настоящая проблема заключается в том, что ваш 32-битный процесс имеет адресное пространство от 2 до 4 ГБ, в зависимости от вашей ОС, и независимо от того, был ли вы осведомлен о своем крупном адресе. Поиск целых гигабайт смежного адресного пространства будет сложным.

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