Огромная поддержка файлов для Delphi 6? (замена системного модуля?)

У меня проблемы с взаимодействием с огромным файлом данных фиксированной длины. Размер файла превышает 14 ГБ. Я впервые заметил проблему, когда увидел возвращаемое значение из System.Filesize() Функция была намного меньше, чем фактическое количество записей в огромном файле, учитывая количество байтов в файле и длину каждой записи. (System.Filesize возвращает количество записей в нетипизированном файле, учитывая размер записи, указанный во время Reset() вызов. Это не возвращает количество байтов в файле). Я записал это на счет типа возврата System.Filesize() будучи Longint вместо Int64.

Я обошел начальную проблему, позвонив GetFileSizeEx() и вычисление количества записей самостоятельно. К несчастью, BlockRead() также происходит сбой при попытке доступа к записям в файле, смещение которых находится глубоко в файле. Я предполагаю, что снова есть значения, которые используются где-то в коде.

Существует ли модуль замены для Delphi 6, который может обрабатывать огромные файлы и является заменой для вызовов ввода-вывода файлов системного блока? Я стараюсь не кататься, если могу.

4 ответа

Вы можете использовать GpHugeFile от gabr. Я сам использовал эту библиотеку для доступа к большим файлам (> 2 ГБ) из Delphi 7. В любом случае, в вашем случае вы должны попытаться изменить логику вашего приложения и перейти на схему базы данных, которая гораздо более эффективна, чем схема, основанная на файлах записей.

Попробуйте TGpHugeFile.

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

// Some constants
const
    kernel = 'kernel32.dll';


function SetFilePointerEx(hFile: Integer; distanceToMove: Int64; var newFilePointer: Int64; moveMethod: DWORD): boolean; stdcall; external kernel name 'SetFilePointerEx';


// easyGetFileSize() is a replacement filesize function.  Use it to get the number of bytes in the huge file.  To get the number of records just "div" it by the record size.

function GetFileSizeEx(hFile: THandle; var FileSize: Int64): BOOL; stdcall; external 'kernel32.dll' name 'GetFileSizeEx';


function easyGetFileSize(theFileHandle: THandle): Int64;
begin
    if not GetFileSizeEx(theFileHandle, Result) then
        RaiseLastOSError;
end;

// ---- Replacement seek function.  Use this instead.

procedure mySeek(var f: File; recordSize, recNum: Int64);

var
    offsetInBytes, numBytesRead: Int64;
    pBigInt: ^Int64;
begin
    offsetInBytes := recNum * recordSize;

    pBigInt := nil; // Not interested in receiving a new pointer after seek.

    // Call the Windows seek call since Delphi 6 has problems with huge files.
    if not SetFilePointerEx(TFileRec(f).Handle, offsetInBytes, pBigInt^, FILE_BEGIN) then
        raise Exception.Create(
            '(mySeek) Seek to record number # '
            + IntToStr(recNum)
            + ' failed');
end;

Вы не можете использовать ввод / вывод Pascal с такими огромными файлами, как ни в одной версии Delphi. Лучше всего использовать TFileStream который не имеет таких ограничений.

Другие вопросы по тегам