[comp.lang.pascal] more fun things to do with files

chem4m@jetson.uh.edu (08/16/90)

If i have TWO  datastructures w/ NO pointers, and I know that i am only going
to save one of each and accordingly will read only one of each, How would
I save these both into ONE file.
To save them into two files would be an easy matter...
TP has a type file; which is an untyped file, but the reset/rewrite command
asks for the byte size of the data structure and as I can call reset/rewrite
only once (since it resets to the beginning of the data file) the untyped file;
format defeats it's own purpose for me.

Any help in this matter would be greatly appreciated
Avijit Ghosh  chem4m.jetson.uh.edu
by the way 
  reset(f,1) { set the byte size to one }
  blockread(f,c,sizeof(c),recordread);
doesn't work either..

John G. Spragge <SPRAGGEJ@QUCDN.QueensU.CA> (08/17/90)

Not that much of a problem, since you can save each data structure as
a string of bytes. For example, consider the following:

  TYPE
     astruct = RECORD        { one data structure                  }
                 i : LONGINT;   { and other good things...         }
               END;

     bstruct = RECORD        { another data structure              }
                 s : STRING [100]; { and anything else you want... }
               END;

  VAR
     fds     : astruct;      { first data structure                }
     sds     : bstruct;      { second data structure               }
     saver   : FILE;         { untyped file to save f and s        }

  BEGIN
     fds.i := 100;
     sds.s := 'NO TYPE, BUT STILL SOME CLASS');

     REWRITE (saver, 1);     { saver is a file of BYTES            }
     BLOCKWRITE (saver, fds, SIZEOF (fds)); { write fds byte by byte }
     BLOCKWRITE (saver, sds, SIZEOF (sds)); { write sds byte by byte }
     CLOSE (saver);                         { finished writing... }

     RESET (saver, 1);        { open the file to read the data back }
     BLOCKREAD (saver, fds, SIZEOF (fds));  { read the first structure }
     BLOCKREAD (saver, sds, SIZEOF (sds));  { read the second structure }

     WRITELN (fds.i, ' ... ', sds.s);
  END.

Moral of the story: if you tell TURBO the (untyped) file record is
1 byte, you can get it to read your data byte by byte into your
data structures.

Disclaimer: I represent no one but myself, and none of this is
            guaranteed to work on your compiler.

               John Spragge

rio@tension.me.utoronto.ca (Oscar del Rio) (08/17/90)

In article <6789.26caaab3@jetson.uh.edu> chem4m@jetson.uh.edu writes:
> If i have TWO  datastructures w/ NO pointers, and I know that i am only going
> to save one of each and accordingly will read only one of each, How would
> I save these both into ONE file.

The following program can help.

It is necessary to define a third dynamic data structure of type RECORD
(as DataType below) which contains both data structures. (I don't remember
how this type of record is called). Well, in fact, this record will
contain only ONE of the structures at a time, and its size is the size of
the greatest data structure + 1 (the flag).

If you are using TP 5.5, test it with the debugger (F8) and with Data1, Data2 
and Data in the Watch Window.

This method can be used for any number of data structures.

---- CUT HERE ----

program Test;

type Data1Type = record        { First data structure (any type) }
           a : string[30];
           b : byte;
           c : set of char;
     end;

     Data2Type = record        { Second data structure (any type) }
           d : string;
           e : real;
           f : char;
     end;

     DataType = record         { Dynamic data structure }
        case flag:byte of
           1: (D1:Data1Type);
           2: (D2:Data2Type);
     end;

var Data1 : Data1Type;
    Data2 : Data2Type;
    Data : DataType;

    f : file of DataType;

begin
  FillChar (Data,SizeOf(Data),0);
  FillChar (Data1,SizeOf(Data1),0);
  FillChar (Data2,SizeOf(Data2),0);

  Data1.a := 'Structure 1';
  Data1.b := 1;
  Data1.c := ['a','b','c'];

  Data2.d := 'Structure 2';
  Data2.e := PI;
  Data2.f := '2';

(***  To save the data :  ***)

  Assign (f,'fname');
  Rewrite (f);

  Data.D1 := Data1;     { to save the first data structure  }
  Data.flag := 1;
  write (f,Data);

  Data.D2 := Data2;     { to save the second data structure }
  Data.flag := 2;
  write (f,Data);

  Close (f);

  FillChar (Data,SizeOf(Data),0);
  FillChar (Data1,SizeOf(Data1),0);
  FillChar (Data2,SizeOf(Data2),0);

(***  To read the data :  ***)

  Assign (f,'fname');
  Reset (f);

  read (f,Data);            { read the first record  }
  if Data.flag=1 then       { is it Data1 or Data2 ? }
    Data1:=Data.D1
  else
    Data2:=Data.D2;

  read (f,Data);            { read the second record }
  if Data.flag=1 then       { is it Data1 or Data2 ? }
    Data1:=Data.D1
  else
    Data2:=Data.D2;

  Close (f);
end.

---- CUT HERE ----

Hope this helps!

=====================================
Oscar Ivan del Rio.
Department of Mechanical Engineering
University of Toronto.
=====================================

elmo@uhura.cc.rochester.edu (Eric Cabot) (08/17/90)

using a file of byte. I think this will work. On the other hand
I have a feeling the using APPEND rather than REWRITE maybe used
either with the file of BYTE solution or with the original file
structures. It would be necessary to check the size of the files
and make sure that the program doesn't get confused by the switch
of types. I bet you that it won't because APPEND should simply
involve moving the file pointer to the end of the file before
writing to it. Reading the stuff back in will definitely require
useing either the file of byte approach or the combined record
approach mentioned earlier, memory permitting. 
-- 
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
Eric Cabot                             |  elmo@{uhura | db1}.cc.rochester.edu
      "insert your face here"          |  elmo@urodbv.bitnet
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

rio@tension.me.utoronto.ca (Oscar del Rio) (08/18/90)

In article <8975@ur-cc.UUCP> elmo@uhura.cc.rochester.edu (Eric Cabot) writes:
>using a file of byte. I think this will work. On the other hand
>I have a feeling the using APPEND rather than REWRITE maybe used
>either with the file of BYTE solution or with the original file
>structures....

Hey, don't forget that APPEND can only be used with TEXT files!
If you want to move the file pointer to the end of the file in
non-text files, you have to code it yourself with SEEK after opening
the file with RESET and checking the file size with FILESIZE.

elmo@uhura.cc.rochester.edu (Eric Cabot) (08/18/90)

In article <90Aug17.135039edt.62@tension.me.utoronto.ca> rio@tension.me.utoronto.ca (Oscar del Rio) writes:
>In article <8975@ur-cc.UUCP> elmo@uhura.cc.rochester.edu (Eric Cabot) writes:
>Hey, don't forget that APPEND can only be used with TEXT files!
>If you want to move the file pointer to the end of the file in
>non-text files, you have to code it yourself with SEEK after opening
>the file with RESET and checking the file size with FILESIZE.

 Whoops! I did forget. You're right. Sorry about that folks.
-- 
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
Eric Cabot                             |  elmo@{uhura | db1}.cc.rochester.edu
      "insert your face here"          |  elmo@urodbv.bitnet
=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=

milne@ics.uci.edu (Alastair Milne) (08/19/90)

In <6789.26caaab3@jetson.uh.edu> chem4m@jetson.uh.edu writes:

>If i have TWO  datastructures w/ NO pointers, and I know that i am only going
>to save one of each and accordingly will read only one of each, How would
>I save these both into ONE file.
>To save them into two files would be an easy matter...
>TP has a type file; which is an untyped file, but the reset/rewrite command
>asks for the byte size of the data structure and as I can call reset/rewrite
>only once (since it resets to the beginning of the data file) the untyped file;
>format defeats it's own purpose for me.

>Any help in this matter would be greatly appreciated
>Avijit Ghosh  chem4m.jetson.uh.edu
>by the way 
>  reset(f,1) { set the byte size to one }
>  blockread(f,c,sizeof(c),recordread);
>doesn't work either..

   First, don't bother with BLOCKREAD.  It's for untyped files, 
   and you want typed files.  Also, with typed files, RESET doesn't
   need the record size.

   TYPE  FlRec = record case IsType1Entry:boolean of
		   true:( entry1: MyFirstDataType);
		  false:( entry2: MySecondDataType);
		  end;
    VAR  DataFile: FILE OF FlRec;

    ...
       RESET( DataFile);
       ...
       READ( DataFile, NextRec);
       IF NextRec.IsType1Entry THEN UseType1Structure( NextRec.Entry1)
       else...

    Not without its drawbacks, since every record in the file will be 
    large enough to take the larger of these two, but it should take 
    care of most of the work for you.  I don't know how it's going 
    to affect DOS' disc I/O time.  I understand that a record size which 
    is not a power of two (or perhaps it's "multiple of 128"?) makes
    disc I/O rather slower.

    Hope this helps.

    Alastair Milne

danielce@uluru5.ecr.mu.oz (Daniel Ake CAROSONE) (08/20/90)

In article <6789.26caaab3@jetson.uh.edu>, chem4m@jetson.uh.edu writes:
> If i have TWO  datastructures w/ NO pointers, and I know that i am only going
> to save one of each and accordingly will read only one of each, How would
> I save these both into ONE file.
> To save them into two files would be an easy matter...
> TP has a type file; which is an untyped file, but the reset/rewrite command
> asks for the byte size of the data structure and as I can call reset/rewrite
> only once (since it resets to the beginning of the data file) the untyped file;
> format defeats it's own purpose for me.

In some of the sample code that comes with 5.5, and on the OOPs Manual Update
that also comes with it, there is a definition for a new type stream.

Objects are saved on streams. (it was introduced as a way out of the problem
that you can't say "FILE of <object_identifier>")

Well worth a look, all the code is given, and may give a few ideas.

Daniel Carosone
danielce@ecr.mu.oz.au