I can confirm TDbf doesn't support DBF-files over 2GB.
Probably because positioning is done with an Integer (max 2.147.483.647). And indeed, with the code below it should produce a DBF of over 6GB but it only produces a file of 2.147.484.141 (just over 2GB because the last record is still written).
Creates a test.dbf in c:\temp
procedure TForm1.Button1Click(Sender: TObject);
var
MyDbf: TDbf;
I: integer;
begin
MyDbf := TDbf.Create(nil);
try
MyDbf.FilePathFull := 'c:\temp';
MyDbf.TableName := 'test.dbf';
MyDbf.TableLevel := 7;
with MyDbf.FieldDefs do
begin
Add('Id', ftAutoInc, 0, True); //Autoincrement field called Id
Add('str1', ftString, 80);
Add('str2', ftString, 80);
Add('str3', ftString, 80);
Add('str4', ftString, 80);
Add('str5', ftString, 80);
Add('str6', ftString, 80);
Add('str7', ftString, 80);
Add('str8', ftString, 80);
end;
MyDbf.CreateTable;
MyDbf.Exclusive := True;
MyDbf.Open;
for I := 1 to 10000000 do
begin
MyDbf.Insert;
MyDbf.FieldByName('str1').AsString := IntToStr(I);
Button1.Caption := IntToStr(I);
MyDbf.Post;
end;
MyDbf.Close;
finally
MyDbf.Free;
end;
end;
The problem lies somewhere in TPagesFile (which tdbf uses to read the file (I think). It uses Integers to calculate the file offset which of course doesn't support files over 2GB.
function TPagedFile.ReadRecord(IntRecNum: Integer; Buffer: Pointer): Integer;
var
Offset: Integer;
begin
if FBufferAhead then
begin
Offset := (IntRecNum - FBufferPage) * PageSize;
if (FBufferPage <> -1) and (FBufferPage <= IntRecNum) and
(Offset+RecordSize <= FBufferReadSize) then
begin
// have record in buffer, nothing to do here
end else begin
I leave it up to the experts to comment on this.
But like we stated before... maybe it's easier (if no fix is found) to raw-read the file.