(*
Diese Funktion liest aus einer Datei mit einer beliebigen Anzahl von Records
einer festen Größe (wobei die Dateigröße 2 GB nicht überschreiten darf) die
Reccords in ein Array. Dabei ist für die Funktion irrelevant wieviele Records
sie lesen soll oder wie die Struktur eines Records oder des Arrays ist.
Die Funktion erfüllt gleichzeitig eine zweite Aufgabe:
[...]
xArray : array[] of TMyRecordType;
begin
// Get number of records in the file
dwNumRecordsBefore := ReadFileIntoArray('datei.dat', Nil, 0, sizeof(TMyRecordType));
// Adapt array size
SetLength(xArray, dwNumRecords);
// Read into the array
dwNumRecordsAfter := ReadFileIntoArray('datei.dat', @xArray, dwNumRecordsBefore, sizeof(TMyRecordType));
end;
Wie man sehen kann, holt der erste Aufruf, bei dem die Anzahl zu lesender
Elemente auf Null gesetzt wurde, die Anzahl von Records in der Datei.
Danach wird die Arraygröße angepaßt und das Array wird ausgelesen.
Wenn man will, kann man danach dwNumRecordsAfter und dwNumRecordsBefore
vergleichen.
ACHTUNG: Diese Funktion checkt nicht, ob die Dateigröße ein ganzzahliges
Vielfaches der Recordgröße ist, also quasi ob die Anzahl von Records exakt
paßt. Stattdessen wird die maximale Anzahl von Records ermittelt, die in eine
Datei der entsprechenden Größe passen würden.
*)
function ReadFileIntoArray(
// Holds the filename of the file to read
sFileName:
string;
// Pointer to the first element of a sized array
lpArray: Pointer;
// Number of elements to read
// --> if this is 0 the function returns the number of records in the file
dwNumToRead:DWORD;
// Size of a single record in the file - MUST NOT be zero!!!
dwSizeOfElement: DWORD
// Return number of elements read
): DWORD;
var
hFile: THandle;
// Handle to the file to read
i,
// Loop counter
dwRead,
// Holds the number of read bytes
dwNumrecords: DWORD;
// Holds the number of records to read
lpBuffer:Pointer;
// Intermediate pointer - holds current offset inside array
bError:Boolean;
begin
Result := 0;
bError := False;
// Open file read-only
hFile := CreateFile(@sFileName[1], GENERIC_READ, 0,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
// If successfully opened
if hFile <> INVALID_HANDLE_VALUE
then
try
// Check filesize, get number of records to read!
dwNumRecords := GetFileSize(hFile,
nil);
// Only read if the function succeeds
if dwNumRecords <> INVALID_FILE_SIZE
then
begin
// Calculate the number of elements to read ...
dwNumRecords := dwNumRecords
div dwSizeOfElement;
// If the array pointer is not assigned ...
if dwNumToRead = 0
then
begin
// Return maximum number of records in the file
Result := dwNumRecords;
Exit;
end;
// If the array buffer is NIL
if not Assigned(lpArray)
then
Exit;
// Adjust number of records to read in case the caller wants less records than are in the file
if dwNumToRead < dwNumRecords
then
dwNumRecords := dwNumToRead;
// Read the calculated number of records
for i := 0
to dwNumRecords - 1
do
begin
// Calculate the offset at which to read
lpBuffer := Pointer(DWORD(lpArray) + i * dwSizeOfElement);
// Read the record into the buffer
bError :=
not ReadFile(hFile, lpBuffer, dwSizeOfElement, dwRead,
nil);
// Check for size read - if smaller than required or Error -> quit
if (dwSizeOfElement <> dwRead)
or bError
then
begin
// Fill buffer with zeroes ... - maybe obsolete
ZeroMemory(lpBuffer, dwSizeOfElement);
// Upon failure quit here
Break;
end;
// Set the number of successfully read records
Result := i;
end;
end;
finally
// Close file
CloseHandle(hFile);
end;
end;