What it the preferred method to write a class to a file?
Charles D Hixson
charleshixsn at earthlink.net
Tue Jul 25 23:05:33 PDT 2006
kris wrote:
> 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
>>
>> }
Nice! Thanks.
I'll need to look into what else Mango provides...it may
save me a lot of work.
More information about the Digitalmars-d-learn
mailing list