3

我在与巨大的固定长度记录数据文件交互时遇到问题。该文件的大小超过 14 GB。当我看到System.Filesize()函数的返回值远小于大文件中的实际记录数时,我首先注意到一个问题,考虑到文件中的字节数和每条记录的长度。(给定调用期间指定的记录大小,System.Filesize 返回无类型文件中的记录数Reset()。它不返回文件中的字节数)。System.Filesize()我将其归结为 Longint 而不是 Int64的返回类型。

GetFileSizeEx()我通过自己调用和计算记录数来解决最初的问题。不幸的是,BlockRead()尝试访问文件中偏移量在文件深处的记录时也会失败。我猜想再次有正在使用的值在代码中的某处溢出。

那里是否有可以处理大型文件的 Delphi 6 替代模块,并且可以替代系统单元文件 I/O 调用?如果可以的话,我会尽量避免自己动手。

4

4 回答 4

6

您可以使用GpHugeFilePrimoz Gabrijelcic的。我自己使用这个库从 Delphi 7 访问更大的文件(> 2gb)。无论如何,在您的情况下,您必须考虑尝试更改应用程序逻辑并迁移到数据库方案,该方案比基于记录文件的方案更有效。

于 2011-05-18T21:57:38.503 回答
2

试试TGpHugeFile

于 2011-05-18T22:01:25.967 回答
2

事实证明,系统单元使用的内部查找例程也由于使用了低容量数字类型而存在问题。我编写了自己对 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;
于 2011-05-18T22:18:24.407 回答
1

你不能在像这样的大文件中使用 Pascal I/O,而不是在任何版本的 Delphi 中。您最好的选择是使用TFileStream没有此类限制的 a。

于 2011-05-18T21:59:30.210 回答