2004. október 12., kedd
How to store and retrieve a text file in / from a resource
Problem/Question/Abstract:
I am trying to work out how to store approximately 1000 lines of text (3 columns, 30 chars each) inside an application. I do not want to have any .INI entries and would prefer not to use an external file.
Answer:
You can start with one and embed it into a resource. Let's assume you have the data in a normal textfile. Make a resource script file (filedata.rc) with a line like
FILEDATA RCDATA filedata.txt
Add this RC file to your Delphi 5 project group. This automatically gets you a $R line for it in the project DPR file and the resource is compiled for you when you build the project. Now, how to get at the data at runtime? Each line is a fixed length of 90 characters. So the file could be represented as an array of records of this type:
type
TFileData = packed record
col1, col2, col3: array[1..30] of Char;
crlf: array[1..2] of Char;
end;
PFileData = ^TFileData;
Let's use a class to regulate access to the data. I assume you only need to read it, so there is no need to copy it from the resource.
type
TDatahandler = class
private
FData: TList;
FResHandle: THandle;
function GetRecord(index: Integer): TFileData;
procedure GetRecordCount: Integer;
procedure InitDatalist;
public
constructor Create;
destructor Destroy; override;
property Records[index: Integer]: TFileData read GetRecord;
property Recordcount: Integer read GetRecordcount;
end;
implementation
constructor TDatahandler.Create;
begin
inherited;
FData := TList.Create;
InitDatalist;
end;
destructor TDatahandler.Destroy;
begin
Fdata.Free;
if FResHandle <> 0 then
begin
UnlockResource(FResHandle);
FreeResource(FResHandle);
end;
inherited;
end;
function TDatahandler.GetRecord(index: Integer): TFileData;
begin
Result := PFileData(FData[i])^;
end;
procedure TDatahandler.GetRecordCount: Integer;
begin
Result := FData.Count;
end;
procedure TDatahandler.InitDatalist;
var
dHandle: THandle;
pData: PFileData;
numRecords, i: Integer;
begin
pData := nil;
dHandle := FindResource(hInstance, 'FILEDATA', RT_RCDATA);
if dHandle <> 0 then
begin
numRecord := SizeofResource(hInstance, dHandle) div Sizeof(TFiledata);
FResHandle := LoadResource(hInstance, dHandle);
if FResHandle <> 0 then
begin
pData := LockResource(dHandle);
if pData <> nil then
begin
FData.Capacity := NumRecords;
for i := 1 to Numrecords do
begin
FData.Add(pData);
Inc(pData);
end;
end
else
raise Exception.Create('Lock failed');
end
else
raise Exception.Create('Load failed');
end
else
raise Exception.Create('Resource not found');
end;
You can add a method to sort the FData list, for example, or a filter method that would populate another TList with pointer to records that match a set of criteria.
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése