What it the preferred method to write a class to a file?

kris foo at bar.com
Tue Jul 25 19:35:03 PDT 2006


just an FYI ~ Mango has supported this for years now:

class Vec : IReadable, IWritable
{
    float[] vec;
    char[]  sig;

    void read (IReader input)
    {
       input (sig) (vec);
    }

    void write (IWriter output)
    {
       output (sig) (vec);
    }
}


void main()
{
    auto vec = new Vec;

    auto f = new FileConduit ("myfile", FileConduit.ReadWriteCreate);
    auto write = new Writer (f);
    auto read = new Reader (f);

    // write and flush
    write (vec) ();

    // rewind and read
    f.seek (0);
    read (vec);
}

Reader/Writer has endian versions, and text versions ...




Charles D Hixson wrote:
> Well, here's where I am now.
> Granted the get and save aren't totally general...but it
> demonstrates where I'm headed.  I plan to save several
> different instances of different classes to the same file.
> (And, of course, to keep an index...which I'll need to write
> just as I close the file...or possibly to keep in a separate
> file.)
> 
> 
> 
> ------------------------------------------------------------------------
> 
> class Vec
> {  protected   float[]  vec;
>    const char[4]  sig   =  "nVec";
> 
> // constructors
> 
>    this(int len, float val)
>    {  initRand();
>       vec.length  =  len;
>       for   (int i = 0; i < vec.length;   i++)  vec[i]   =  val;
>    }
> 
> // a lot of stuff was removed here
> 
> 
>   /**
>    *  Export the object to a seekable stream.  The format is only
>    *  intended for computers, but it should be lossless.
>    *  The returned value is the stream address of the start of the object.
>    */
>    ulong write(Stream s)
>       in
>       {  assert (s.isOpen());
>          assert (s.writeable);
>          assert (s.seekable);
>       }
>       body
>       {  ulong oStart   =  s.position;
>          s.write(cast(uint)0);
>          s.write(char4ToUint(sig));
>          s.write(cast(uint)(this.vec.length));
>          foreach(float f;  this.vec)   s.write(f);
>          s.write(eor);
>          ulong oEnd  =  s.position;
>          s.position(oStart);
>          s.write(cast(uint)(oEnd - oStart) );
>          s.position(oEnd);
>          return   oStart;
>       }
> 
>   /**
>    *  Import the object from a seekable stream.  The format is only
>    *  intended for computers, but it should be lossless.
>    */
>    static   Vec   get(Stream s)
>       in
>       {  assert (s.isOpen());
>          assert (s.readable);
>          assert (s.seekable);
>       }
>       body
>       {  ulong oStart   =  s.position;
>          Vec   v  =  new   Vec();
>          uint  len, vlen, veor, tmpSig2;
>          char[]   sig2;
>          s.read(len);
>          s.read(tmpSig2);
>          sig2  =  uintToChar4(tmpSig2);
>          if (sig != sig2)
>          {  s.position(oStart);
>             writefln("original signature = <", sig, ">");
>             writefln("read in signature  = <", sig2, ">");
>             throw new   Exception ("Vec:get: Signature mismatch");
>          }
>          s.read(cast(uint)(vlen));
>          v.length =  vlen;
>          for(int i = 0; i < vlen;   i++)  s.read(v.vec[i]);
>          s.read(veor);
>          if (eor != veor)
>          {  s.position(oStart);
>             throw new   Exception ("Vec:get: eor not detected when expected");
>          }
>          ulong oEnd  =  s.position;
>          if (len != cast(uint)(oEnd - oStart) )
>          {  s.position(oStart);
>             writefln("length calculated = %d", len);
>             writefln("length read       = %d", cast(uint)(oEnd - oStart));
>             throw new   Exception
>                   ("Vec:get: length calculated does not match length read");
>          }
>          return   v;
>       }  // get
> 
> }



More information about the Digitalmars-d-learn mailing list