[comp.lang.pascal] Saving dynamic structures to disk & recalling revisited....

wct@po.CWRU.Edu (William C. Thompson) (04/22/91)

I did some more work on saving dynamically sized structures
to disk.  I have almost perfected it, but it's a bit slow.
It works beautifully, though...

type
  buffer=array[1..64000] of byte;

procedure saveimage(x1,y1,x2,y2:word; fn:string; var size:word);
{ This procedure captures an image from the screen and writes
  it to the specified file and returns the size.  There is no error
  checking as to how much memory is available.  The size of an image
  is the number of pixels divided by two plus 6 (VGA mode) }
var
  f: file of byte;
  p: ^buffer;
  i: word;
begin
  size:=imagesize(x1,y1,x2,y2);
  getmem(p,size);                 { allocate space }
  getimage(x1,y1,x2,y2,p^);       { capture the image from screen }
  assign(f,fn);
  rewrite(f);
  for i:=1 to size do write(f,p^[i]);  { write image to disk }
  freemem(p,size);                { return memory }
  close(f);
end;

procedure recallimage(x1,y1:word; fn: string; size:word; wput:byte);
{ This procedure reads in an image from the specified file
  and puts the image on the screen }
var
  f: file of byte;
  p: ^buffer;
  i: word;
begin
  getmem(p,size);                { allocate space }
  assign(f,fn);                  { prepare file }
  reset(f);
  for i:=1 to size do read(f,p^[i]);        { read in the image }
  close(f);
  putimage(x1,y1,p^,wput);       { put image on screen }
  freemem(p,size);               { return memory }
end;


The only drawback at all is that the part where I read from and 
write to a file is slow.  I tried BlockWrite and BlockRead,
but those made my files WAY too big.  The file sizes didn't
match the number of bytes I told it to write.  Here is the code
I used ---

BlockRead(f,p^,size,n)      &     BlockWrite(f,p^,size,n)

Where f: FILE and n: WORD

Anyone see any problems with this code?  I'm not quite sure what 
that 4th parameter is for, either.  I think it's for confirmation 
of how got written to disk, but I'm not sure.  There was a buffer 
I used that should have been around 7.5K, but the file size was 
40K!  That seems like a huge gap to me.  Anyone with advice or
experience in these matters please E-mail me so I can wrap this
business up.

Thanx in advance
-- 
Ticking away, the moments that make up a dull day.   | William C. Thompson
You fritter and waste the hours in an offhand way.   | Michelson 620D (wct)
Kicking around on a piece of ground in your hometown,| a.k.a. Master of Time,
waiting for someone or something to show you the way.| Space, and Dimension

wct@po.CWRU.Edu (William C. Thompson) (04/22/91)

In a previous article, wct@po.CWRU.Edu (William C. Thompson) says:

I managed to fix my own problem...  Here is the solution, though.

>type
>  buffer=array[1..64000] of byte;
>
>procedure saveimage(x1,y1,x2,y2:word; fn:string; var size:word);
>{ This procedure captures an image from the screen and writes
>  it to the specified file and returns the size.  There is no error
>  checking as to how much memory is available.  The size of an image
>  is the number of pixels divided by two plus 6 (VGA mode) }
>var
>  f: file of byte;
      ^^^^^^^^^^^^   Change this to just plain FILE

>  p: ^buffer;
>  i: word;
>begin
>  size:=imagesize(x1,y1,x2,y2);
>  getmem(p,size);                 { allocate space }
>  getimage(x1,y1,x2,y2,p^);       { capture the image from screen }
>  assign(f,fn);

>  rewrite(f);
>  for i:=1 to size do write(f,p^[i]);  { write image to disk }

Replace these lines with 

rewrite(f,1)    { tells compiler file's object size is 1 }
blockwrite(f,p^,size,dummy)

>  freemem(p,size);                { return memory }
>  close(f);
>end;
>
>procedure recallimage(x1,y1:word; fn: string; size:word; wput:byte);
>{ This procedure reads in an image from the specified file
>  and puts the image on the screen }
>var
>  f: file of byte;           
      ^^^^^^^^^^^^    Same here...
>  p: ^buffer;
>  i: word;
>begin
>  getmem(p,size);                { allocate space }
>  assign(f,fn);                  { prepare file }

>  reset(f);
>  for i:=1 to size do read(f,p^[i]);        { read in the image }

Replace these two lines by 
reset(f,1);
blockread(f,p^,size,dummy)

>  close(f);
>  putimage(x1,y1,p^,wput);       { put image on screen }
>  freemem(p,size);               { return memory }
>end;

>The only drawback at all is that the part where I read from and 
>write to a file is slow.  I tried BlockWrite and BlockRead,
>but those made my files WAY too big.  The file sizes didn't
>match the number of bytes I told it to write.  Here is the code
>I used ---
>
>BlockRead(f,p^,size,n)      &     BlockWrite(f,p^,size,n)

I think the main problem was that I didn't tell the compiler
how big the file's objects were.  Once I made that change,
everything fell into place.
-- 
Ticking away, the moments that make up a dull day.   | William C. Thompson
You fritter and waste the hours in an offhand way.   | Michelson 620D (wct)
Kicking around on a piece of ground in your hometown,| a.k.a. Master of Time,
waiting for someone or something to show you the way.| Space, and Dimension

Harold.Ruby@f1999.n106.z1.fidonet.org (Harold Ruby) (04/24/91)

    Try this:

procedure savescreen;
var image:file;
begin
  assign (image,'FILENAME.EXT');
  rewrite (image,1);
  blockwrite (image,mem[$A000,0],$FA00);
end;

procedure restorescreen;
var image:file;
begin
  assign (image,'FILENAME.EXT');
  reset (image,1);
  blockread (image,mem[$A000,0],$FA00);
end;

Note - I've left out error correction / file exist checking / etc.. 

Harold