Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 28, 2011 r/w binary | ||||
---|---|---|---|---|
| ||||
I want to save and load levels for my game. The std.stream module doesn't have much examples. Here is my code: void saveLevel( string fileName ) { auto bfile = new std.stream.File; int ver = 1; string verStr = "version:"; with( bfile ) { scope( exit ) close; create( fileName ); write( verStr ); write( ver ); // version } int ver2; char[] verStr2; auto bfile2 = new std.stream.File; with( bfile2 ) { scope( exit ) close; create( fileName ); read( verStr2 ); read( ver2 ); // version } writeln( verStr, ver ); } And this is the result: std.stream.ReadException@std\stream.d(46): Stream is not readable - Joel |
June 29, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joel Christensen | I've settled on std.stdio as opposed to std.stream and std.cstream. On Wed, 29 Jun 2011 10:07:13 +1200, Joel Christensen wrote: > I want to save and load levels for my game. The std.stream module doesn't have much examples. > > Here is my code: > void saveLevel( string fileName ) { > auto bfile = new std.stream.File; > > int ver = 1; > string verStr = "version:"; > with( bfile ) { > scope( exit ) > close; > create( fileName ); > write( verStr ); write( ver ); // version > } > > int ver2; > char[] verStr2; > auto bfile2 = new std.stream.File; > with( bfile2 ) { > scope( exit ) > close; > create( fileName ); That is copy-paste mistake, right? You don't want create() before reading. You must have meant open: open( fileName ); It works with that change. > read( verStr2 ); read( ver2 ); // version > } > writeln( verStr, ver ); > } > > And this is the result: > std.stream.ReadException@std\stream.d(46): Stream is not readable > > - Joel Ali |
June 29, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Thanks for your reply Ali.
Your right about changing create to open when reading. And, yes, I was thinking of trying std.stdio myself.
- Joel
On 29-Jun-11 6:48 PM, Ali Çehreli wrote:
> I've settled on std.stdio as opposed to std.stream and std.cstream.
>
> On Wed, 29 Jun 2011 10:07:13 +1200, Joel Christensen wrote:
>
>> I want to save and load levels for my game. The std.stream module
>> doesn't have much examples.
>>
>> Here is my code:
>> void saveLevel( string fileName ) {
>> auto bfile = new std.stream.File;
>>
>> int ver = 1;
>> string verStr = "version:";
>> with( bfile ) {
>> scope( exit )
>> close;
>> create( fileName );
>> write( verStr ); write( ver ); // version
>> }
>>
>> int ver2;
>> char[] verStr2;
>> auto bfile2 = new std.stream.File;
>> with( bfile2 ) {
>> scope( exit )
>> close;
>> create( fileName );
>
> That is copy-paste mistake, right? You don't want create() before
> reading. You must have meant open:
>
> open( fileName );
>
> It works with that change.
>
>> read( verStr2 ); read( ver2 ); // version
>> }
>> writeln( verStr, ver );
>> }
>>
>> And this is the result:
>> std.stream.ReadException@std\stream.d(46): Stream is not readable
>>
>> - Joel
>
> Ali
|
June 29, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joel Christensen | With the char[], I can't use spaces in it the way I've got it here, (like if I tried using a phrase): void saveLevel( string fileName ) { int ver = 1; auto house = "two".dup; double rnum = 3.0; { auto fout = File( fileName, "wb"); // open for binary writing scope( exit ) fout.close; fout.writef( "%d %s %f", ver, house, rnum ); } ver = 593; house = "asdfghf".dup; rnum = 57.23; { auto fin = File( fileName, "rb"); // open for binary reading scope( exit ) fin.close; fin.readf( "%d %s %f", &ver, &house, &rnum ); } writeln( "\nint: ", ver, " string: '", house, "' rnum: ", rnum ); } - Joel |
June 29, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joel Christensen | On Wed, 29 Jun 2011 19:55:38 +1200, Joel Christensen wrote: > With the char[], I can't use spaces in it the way I've got it here, > (like if I tried using a phrase): There has been a thread very recently about reading strings. Look for the thread "readf with strings" (dated 22-Jun-2011 in my reader). Or, if it works here: http://www.digitalmars.com/webnews/newsgroups.php? art_group=digitalmars.D.learn&article_id=27762 Reading the entire line: string s = chomp(readln()); Kai Meyer suggested parsing the string directly: string[] buffer; int a; float b; string c; buffer = chomp(readln()).split(" "); a = to!(int)(buffer[0]); b = to!(float)(buffer[1]); c = buffer[2..$].join(" "); writef("Read in: '%d' '%f' '%s'\n", a, b, c); > > void saveLevel( string fileName ) { > int ver = 1; > auto house = "two".dup; > double rnum = 3.0; > > { > auto fout = File( fileName, "wb"); // open for binary writing scope( > exit ) > fout.close; You are not supposed to need to close the File object yourself. Being a struct, its destructor should be called automatically. Ali |
June 30, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | I'm thinking more about handling binary files. With the C version I would write a int for how many letters in the string, then put in the the string along side ([0005][house]). That way I can have any character at all (though I just thinking of char's).
Actually, I've just looked the output file and it's a text file. So in that case I would use read line to have spaces in strings, though what if I wanted to have new line character(s) in the one string. I still want to work with binary files.
On 30-Jun-11 2:23 AM, Ali Çehreli wrote:
> On Wed, 29 Jun 2011 19:55:38 +1200, Joel Christensen wrote:
>
>> With the char[], I can't use spaces in it the way I've got it here,
>> (like if I tried using a phrase):
>
> There has been a thread very recently about reading strings. Look for the
> thread "readf with strings" (dated 22-Jun-2011 in my reader). Or, if it
> works here:
>
> http://www.digitalmars.com/webnews/newsgroups.php?
> art_group=digitalmars.D.learn&article_id=27762
>
> Reading the entire line:
>
> string s = chomp(readln());
>
> Kai Meyer suggested parsing the string directly:
>
> string[] buffer;
> int a;
> float b;
> string c;
> buffer = chomp(readln()).split(" ");
> a = to!(int)(buffer[0]);
> b = to!(float)(buffer[1]);
> c = buffer[2..$].join(" ");
> writef("Read in: '%d' '%f' '%s'\n", a, b, c);
>
>>
>> void saveLevel( string fileName ) {
>> int ver = 1;
>> auto house = "two".dup;
>> double rnum = 3.0;
>>
>> {
>> auto fout = File( fileName, "wb"); // open for binary
> writing scope(
>> exit )
>> fout.close;
>
> You are not supposed to need to close the File object yourself. Being a
> struct, its destructor should be called automatically.
>
> Ali
|
June 30, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joel Christensen | On Thu, 30 Jun 2011 15:52:59 +1200, Joel Christensen wrote: > I'm thinking more about handling binary files. With the C version I would write a int for how many letters in the string, then put in the the string along side ([0005][house]). That way I can have any character at all (though I just thinking of char's). I would still use a portable text format myself. For binary, you should consider rawWrite() and rawRead(). Here is just a start: import std.stdio; void main() { int i = 42; auto file = File("deleteme.bin", "w"); file.rawWrite((&i)[0..1]); } (Aside: The 'b' for binary mode does nothing in POSIX systems; so it's not necessary.) The parameter to rawWrite() above is a nice feature of D: slicing a raw pointer produces a safe slice: http://digitalmars.com/d/2.0/arrays.html <quote> Slicing is not only handy for referring to parts of other arrays, but for converting pointers into bounds-checked arrays: int* p; int[] b = p[0..8]; </quote> For strings (actually arrays), you would need .length and .ptr properties. I've never used it but you might want to consider the serialization library Orange as well: http://www.dsource.org/projects/orange Ali |
June 30, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Yes, portability, I hadn't thought of that.
Shouldn't file.rawWrite((&i)[0..1]); have [0..4]? Or am I missing some thing?
- Joel
On 30-Jun-11 7:53 PM, Ali Çehreli wrote:
> On Thu, 30 Jun 2011 15:52:59 +1200, Joel Christensen wrote:
>
>> I'm thinking more about handling binary files. With the C version I
>> would write a int for how many letters in the string, then put in the
>> the string along side ([0005][house]). That way I can have any character
>> at all (though I just thinking of char's).
>
> I would still use a portable text format myself.
>
> For binary, you should consider rawWrite() and rawRead(). Here is just a
> start:
>
> import std.stdio;
>
> void main()
> {
> int i = 42;
> auto file = File("deleteme.bin", "w");
> file.rawWrite((&i)[0..1]);
> }
>
> (Aside: The 'b' for binary mode does nothing in POSIX systems; so it's
> not necessary.)
>
> The parameter to rawWrite() above is a nice feature of D: slicing a raw
> pointer produces a safe slice:
>
> http://digitalmars.com/d/2.0/arrays.html
>
> <quote>
> Slicing is not only handy for referring to parts of other arrays, but for
> converting pointers into bounds-checked arrays:
>
> int* p;
> int[] b = p[0..8];
> </quote>
>
> For strings (actually arrays), you would need .length and .ptr properties.
>
> I've never used it but you might want to consider the serialization
> library Orange as well:
>
> http://www.dsource.org/projects/orange
>
> Ali
|
June 30, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joel Christensen | On Fri, 01 Jul 2011 05:28:56 +1200, Joel Christensen wrote:
> Shouldn't file.rawWrite((&i)[0..1]); have [0..4]? Or am I missing some
> thing?
[0..1] follows the regular slicing syntax there: those are element indexes. Since &i is an int*, [0..1] slices the first int. It would be different if it were ubyte* or void*.
Ali
|
July 01, 2011 Re: r/w binary | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | Ok, I get you. A whole int*, not one byte of the int* data.
- Joel
On 01-Jul-11 6:07 AM, Ali Çehreli wrote:
> On Fri, 01 Jul 2011 05:28:56 +1200, Joel Christensen wrote:
>
>> Shouldn't file.rawWrite((&i)[0..1]); have [0..4]? Or am I missing some
>> thing?
>
> [0..1] follows the regular slicing syntax there: those are element
> indexes. Since&i is an int*, [0..1] slices the first int. It would be
> different if it were ubyte* or void*.
>
> Ali
|
Copyright © 1999-2021 by the D Language Foundation