I am creating a binary file, containing a record type i have defined, using the BLockWrite command.

I am then trying to read the data back again and i get 3 out of the 4 values in the record back and i can't work out why.

Code snippets below
Bits of Code below:

TYPE TTileRecord = PACKED Record
Min,Max,Avg,Std : Double
END; {TTileRecord}

RecTile : TTileRecord;
BIP : File;
iCount, iTransfer : Integer;
ReadBIP : File;

WHILE NOT EOF DO BEGIN
//RecTile.sTileName := UpperCase(FieldAsString('TILE_NAME'));
RecTile.Min := FieldAsFloat('MIN_DISTANCE');
RecTile.Max := FieldAsFloat('MAX_DISTANCE');
RecTile.Avg := FieldAsFloat('AVG_DISTANCE');
RecTile.std := FieldAsFloat('STD_DISTANCE');

BlockWrite(BIP,RecTile,iCount,iTransfer);
Next; 
END;

iSeek := 0 //read the first record
Seek(ReadBIP,iSeek);
BlockRead(ReadBIP,RecTile,SizeOf(recTile),iRead);

When it runs it gives me:
iCount = 31
iTransfer = 31
SizeOf(recTile) = 32
iRead 32

I tried to do SizeOf(recTile)-1 but this didn't make any difference.
The values that were input were:
Min := 706503
Max:= 838374
Avg:=780866.691
Std:= 35813.041

It reads the first three fine but the std comes back as 1.9921665331e-304

Does anyone know how to fix this? (I am using Delphi 7)
Cheers
SeaZoneDev

Recommended Answers

All 7 Replies

Shouldn't you be using iCount instead of SizeOf(recTile) in the BlockRead ?

Thanks
tried that by doing

BlockRead(ReadBIP,RecTile,SizeOf(recTile)-1,iRead);

and that didn't work - i got the correct first three values, then the last was still wrong.

If it is any help here are the full two functions that I am using.

FUNCTION TCreateIndex_frm.CreateIndex(Session : TOracleSession; sExportPath : String) : Boolean;
VAR
 RecTile : TTileRecord;
 BIP : File;
 iCount, iTransfer : Integer;
 iLat,iLon : Integer;
BEGIN
  TRY
  DeleteFile(ChangeFileExt(sExportPath+'Index','.bip'));
  CreateFile(ChangeFileExt(sExportPath+'Index','.bip'));
  AssignFile(BIP,ChangeFileExt(sExportPath+'Index','.bip'));
  Reset(BIP,1);

  WITH TOracleQuery.Create(Session) DO TRY

     //WHILE True DO TRY //Keep Going until you stop!
       Session:=(Owner AS TOracleSession);
       WITH Session DO IF NOT Connected THEN LogOn;


       SQL.Text:='SELECT TILE_NAME ,MIN_DISTANCE,MAX_DISTANCE, AVG_DISTANCE,STD_DISTANCE,TILE_LAT, TILE_LON '
                +'FROM GRID_TILES '
                +'ORDER BY TILE_LAT DESC,TILE_LON';
       Execute;

       WHILE NOT EOF DO BEGIN
           //RecTile.sTileName :=  UpperCase(FieldAsString('TILE_NAME'));
           RecTile.Min :=  FieldAsFloat('MIN_DISTANCE');
           RecTile.Max :=  FieldAsFloat('MAX_DISTANCE');
           RecTile.Avg :=  FieldAsFloat('AVG_DISTANCE');
           RecTile.std :=  FieldAsFloat('STD_DISTANCE');

           BlockWrite(BIP,RecTile,iCount,iTransfer);
           
          Next;
       END;
       MessageDlg('Finished',mtInformation,[mbOK],1);
    FINALLY
    END;

  FINALLY
    CloseFile(BIP);
  END;
END; {FUNCTION CreateIndex}

FUNCTION TfrmMainZynetix.GetMinMax(sInputPath: String; fLat, fLon : Double) : TTileRecord;
VAR
  ReadBIP : File;
  RecTile : TTileRecord;
  icount, iRead : Integer;
  iLat, iLon : Integer;
  iRow, iCol, iSeek : Integer;
  iBinSize : Integer;
  iPosInStr : Integer;
begin

  GisReleaseNA;
  AssignFile(ReadBIP,ChangeFileExt(sInputPath+'Index','.bip'));
  Reset(ReadBIP,1);

  iLat := GetIntValFromPos(fLat);
  iLon := GetIntValFromPos(fLon);

  //iLat := 90;
  //iLon := -180;
  iBinSize := 2;

  //Calculate Row Position
  iRow := Abs(iLat -90) ;
  iRow := iRow Div iBinSize;
  //Calculate Col Position
  iCol := Abs(iLon +180) ;
  iCol := iCol Div iBinSize;
  //Calculate seek position
  //nRows-1 *360 + dist into row  * size of tileRecord

  iSeek := (((iRow)*(360 Div iBinSize)) + iCol)* SizeOf(RecTile);


  Seek(ReadBIP,iSeek);
  BlockRead(ReadBIP,RecTile,SizeOf(recTile)+1,iRead);

 // MessageDlg(RecTile.sTileName,mtInformation,[mbOK],1);

  GetMinMax := RecTile;
END; {FUNCTION GetMinMax}

Wouldnt this be easier with a stream? anyway..

your while look of eof hasnt made much sense in this case, as when writing you dont normally test for eof...

when you blockwrite, the params are file,buffer,count, result

Your count doesnt get a value it should read something like

BlockWrite(BIP,TileRec,1,itransfer);


If you know its only 1 record, then thats fine, but if not, you should do filesize / sizeof (rectile), but again, this is supposed to be a count, so again should be 1.

PS - any reason why you're stuck with a very old version of delphi?

In addition to LizR

This:

BlockRead(ReadBIP,RecTile,SizeOf(recTile)+1,iRead);

Should be this:

BlockRead(ReadBIP,RecTile,1,iRead);

Which is what I wrote :P

True, although icount doesnt get set to a value so that wouldnt work without either setting a value, or changing it as we've both said.. either way, hes gone awful quiet :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.