A bit of binary I/O
Heinz
billgates at microsoft.com
Sat Jan 20 16:04:08 PST 2007
Jarrett Billingsley Wrote:
> "Heinz" <billgates at microsoft.com> wrote in message
> news:eou69k$8tf$1 at digitaldaemon.com...
>
> > The first way is to write primitives manually one by one:
> >
> > // primitive way
> > ulong i = 9;
> > char[] s = "hello world";
> > myFile.writeExact(&i, i.sizeof);
> > myFile.writeExact(&s, s.sizeof);
> >
> > Reading data:
> > // Is done by reading each primitive.
> > ulong i2; char[] s2;
> > myFile.readExact(&i2, i2.sizeof);
> > myFile.readExact(&s2, s2.sizeof);
>
> You're writing the string wrong. All you're doing is writing the length and
> pointer of the array data, without actually writing the data.
>
> The Stream class (and by extension, the File class) provides functions for
> writing out every basic type:
>
> ulong i = 9;
> char[] s = "hello world";
> myFile.write(i);
> myFile.write(s);
>
> ...
> ulong i2;
> char[] s2;
> myFile.read(i2);
> myFile.read(s);
>
> > The second way is to write a structure with all the primitives as members:
> >
> > // struct way
> > struct t
> > {
> > ulong i;
> > char[] s;
> > }
> >
> > t mt;
> > mt.i = 9;
> > mt.s = "hello world";
> > myFile.writeExact(&mt, mt.sizeof);
> >
> > Reading data:
> > // We read the entire struct.
> > t mt2;
> > myFile.readExact(&mt2, mt2.sizeof);
>
> Again, you're just writing out the array reference without writing its
> contents. You have to write out each member individually. If there were no
> reference types in the struct, this would work fine.
>
> >
> > And the third way is to write a class with all the primitives as members:
> >
> > // class way
> > class tt
> > {
> > ulong i;
> > char[] s;
> > }
> >
> > tt mtt = new tt();
> > mtt.i = 9;
> > mtt.s = "hello world";
> > ResFile.writeExact(&mtt, mtt.sizeof);
> >
> > Reading data:
> > // We read the entire class.
> > tt mtt2;
> > myFile.readExact(&mtt2, mtt2.sizeof);
> >
>
> This is incorrect, and is only working because of how you've written your
> program. You're not writing the data out at all, you're writing a class
> reference. The 00913FC0 is just the memory address of the class instance
> that mtt points to, and when you read that address back in, you're just
> looking at the data in memory. This program wouldn't work if you write the
> file, exited, then had another program that read the data. You'd end up
> with a memory access violation, and none of the data in the class is
> actually written out.
>
> If you want to write a class out to a file, a common way is to have some
> kind of generic "serialize" and "unserialize" functions for the class:
>
> class C
> {
> ulong i;
> char[] s;
>
> void serialize(Stream s)
> {
> s.write(i);
> s.write(s);
> }
>
> static C unserialize(Stream s)
> {
> C c = new C();
> s.read(c.i);
> s.read(c.s);
> return c;
> }
> }
>
> ...
> C c = new C();
> c.i = 5;
> c.s = "foo";
> c.serialize(myFile);
>
> ...
>
> C c = C.unserialize(myFile);
>
> >
> > All of these methods works perfect. I'm able to retrieve values from all
> > of them. Now lets check at the outputs:
> >
> > // Primitive
> >
> > 09 00 00 00 00 00 00 00 0B 00 00 00 A0 C7 41 00
> >
> > // Structure
> >
> > 09 00 00 00 00 00 00 00 0B 00 00 00 A0 C7 41 00
> >
> > // Class
> >
> > C0 3F 91 00
> >
> > My questions are:
> >
> > 1) What's the best method to write data (in terms of data
> > protection/encryption against reversion). The class way seems to me at
> > first look the most secure way.
>
> As explained before, the class method is wrong, and there is no encryption
> going on here. It's just a memory address, and you should never, ever write
> memory addresses to a file.
>
> That being said, the best way is probably to just use the primitive .read
> and .write methods of File. Just .. never, ever write pointers or
> references of any kind to a file.
>
> > 2) Wich method is the faster in retrieving data?
>
> If you implement them correctly, all three sample programs should make the
> exact same output file using the same number of writes (and read it in the
> same number of reads), and so they are all the same in terms of performance.
>
>
Wow, that covers all, thanks for your reply.
But, can i still write an entire structure with writeExact()? or you suggest writting each member of the structure with write()?
Another question: Writting a type char[] with write() writes string as ASCII? if so then is a legible string, how can i protect that data?
Thanks man
More information about the Digitalmars-d-learn
mailing list