[fpc-pascal] Using TFileStream class
Howard Page-Clark
hdpc at talktalk.net
Wed Mar 4 21:51:11 CET 2009
On Wed, 4 Mar 2009 20:42:14 +0100
Aurélie de LUCA <aureliedeluca at gmail.com> wrote:
> Hy everybody,
>
> I'm trying to use the TFileStream class to read a file with a record,
> and I obtain this message when I execute my application : Access
> violation. You can find my code in the following :
>
> type
> DmatLine= record
> ID1: string;
> ID2: string;
> C: integer;//classe différence 1 if reactions aren't of same
> classe and 0, on the contrary.
> Euclide: double;//Euclidian distance between two reactions.
> Tanimoto: double;//Tanimoto coefficient between two
> reactions. Dice: double;//Dice coefficient between two reactions.
> end;
>
> ....
>
> procedure TReadDmat.ReadDmat(input: string; nbCpd : integer);
> var
> i, j, k, l, m, sizeOfArray, test: integer;
> DmatFile: TFileStream;
> LineRecord1, LineRecord2: DmatLine;
> begin
> if (FileExists(input) )then
> begin
> DmatFile:=TFileStream.Create(input, fmOpenRead);
> try
> DmatFile.Position := 0;
> while (DmatFile.position < DmatFile.size) {NB ^ see
> above..} do begin
> with LineRecord1 do
> begin
> DmatFile.Read(ID1, sizeOf(string));
> DmatFile.Read(ID2, sizeOf(string));
(snip)
One problem is your use of long strings in a record structure. Long
strings can be any size, and the size can change at runtime.
Longstring variables are pointers to dynamically allocated storage, so
Sizeof(string) will always return 4 on 32bit systems.
If DMatLine.ID1 and DmatLine.ID2 are <= 255 characters, you could use
shortstrings, declared e. g. as
type
string40 = string[40];
DmatLine= record
> ID1: string40;
> ID2: string40;
> C: integer;
...
end;
Then the compiler knows exactly how big each record is, and does the
TFileStream.
Howard
More information about the fpc-pascal
mailing list