www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How do I create a new file using phobos ?

reply Ray C Horn <raychorn hotmail.com> writes:
How do I create a new file using phobos ?

More examples in the online docs would be useful.
Sep 21 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Ray C Horn wrote:
 How do I create a new file using phobos ?
 
 More examples in the online docs would be useful.

You can do it several ways. Theres std.c.stdio which has the classic C fopen/fclose API. I usually use std.stream.BufferedFile http://www.digitalmars.com/d/phobos/std_stream.html Ex: char[][] lines; ... { scope Stream file = new BufferedFile("sample.txt",FileMode.Out); foreach(line; lines) { file.writefln(line); } } --bb
Sep 21 2007
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Bill Baxter wrote:
 Ray C Horn wrote:
 How do I create a new file using phobos ?

 More examples in the online docs would be useful.

You can do it several ways. Theres std.c.stdio which has the classic C fopen/fclose API. I usually use std.stream.BufferedFile http://www.digitalmars.com/d/phobos/std_stream.html Ex: char[][] lines; ... { scope Stream file = new BufferedFile("sample.txt",FileMode.Out); foreach(line; lines) { file.writefln(line); } }

Wait a minute, can anyone confirm that it's ok to use a scope BufferedFile without explicitly closing? BufferedFile contiains a 'new File()', but no destructor. The File's destructor contains a close(), however. So will the member File's destructor get called when the scope BufferedFile goes out of scope? It's really just a question of how scope works w.r.t classes with heap allocated members. Do the reference members get deleted deterministically on scope exit too? --bb
Sep 21 2007
next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Bill Baxter wrote:
 Wait a minute, can anyone confirm that it's ok to use a scope 
 BufferedFile without explicitly closing?
 BufferedFile contiains a 'new File()', but no destructor.  The File's 
 destructor contains a close(), however.  So will the member File's 
 destructor get called when the scope BufferedFile goes out of scope?
 
 It's really just a question of how scope works w.r.t classes with heap 
 allocated members.  Do the reference members get deleted 
 deterministically on scope exit too?

No, they don't. You'd have to wait until they get GC'd. Yes, this sucks. Putting "scope(exit) file.close;" right after your declaration should make the case in the example behave properly...
Sep 21 2007
next sibling parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Frits van Bommel wrote:
 Bill Baxter wrote:
 Wait a minute, can anyone confirm that it's ok to use a scope
 BufferedFile without explicitly closing?
 BufferedFile contiains a 'new File()', but no destructor.  The File's
 destructor contains a close(), however.  So will the member File's
 destructor get called when the scope BufferedFile goes out of scope?

 It's really just a question of how scope works w.r.t classes with heap
 allocated members.  Do the reference members get deleted
 deterministically on scope exit too?

No, they don't. You'd have to wait until they get GC'd. Yes, this sucks. Putting "scope(exit) file.close;" right after your declaration should make the case in the example behave properly...

You know what I'd *kill* for? class Llama { string foo; Object bar; scope InputStream baz; scope ubyte[] quxx; ~this() { // Can't do much here; could be GC'ed :'( } scope ~this() { // EVERYBODY DIES!! delete foo; delete bar; // baz automatically gets scope ~this'ed & delete'd. // quxx automatically gets delete'd. } } Yeah, yeah; I'll go back to wishing wistfully... -- Daniel
Sep 21 2007
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Frits van Bommel wrote:
 Bill Baxter wrote:
 Wait a minute, can anyone confirm that it's ok to use a scope 
 BufferedFile without explicitly closing?
 BufferedFile contiains a 'new File()', but no destructor.  The File's 
 destructor contains a close(), however.  So will the member File's 
 destructor get called when the scope BufferedFile goes out of scope?

 It's really just a question of how scope works w.r.t classes with heap 
 allocated members.  Do the reference members get deleted 
 deterministically on scope exit too?

No, they don't. You'd have to wait until they get GC'd. Yes, this sucks. Putting "scope(exit) file.close;" right after your declaration should make the case in the example behave properly...

Aw dangit. Now I've got to go grep through all my code to find everywhere I've used a scope BufferedFile. :-( --bb
Sep 21 2007
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
news:fd27j5$87u$1 digitalmars.com...
 Aw dangit.  Now I've got to go grep through all my code to find everywhere 
 I've used a scope BufferedFile.  :-(

I'm actually very surprised that BufferedFile doesn't have a dtor which flushes and then closes its file. File's dtor closes itself.
Sep 22 2007
parent reply torhu <no spam.invalid> writes:
Jarrett Billingsley wrote:
 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
 news:fd27j5$87u$1 digitalmars.com...
 Aw dangit.  Now I've got to go grep through all my code to find everywhere 
 I've used a scope BufferedFile.  :-(

I'm actually very surprised that BufferedFile doesn't have a dtor which flushes and then closes its file. File's dtor closes itself.

It's a bit annoying, yeah. I think it's because the member object might already be deleted when the containing object's destructor gets called. Can't remember the exact reason for this limitation, but I think it's documented somewhere.
Sep 22 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
torhu wrote:
 Jarrett Billingsley wrote:
 "Bill Baxter" <dnewsgroup billbaxter.com> wrote in message 
 news:fd27j5$87u$1 digitalmars.com...
 Aw dangit.  Now I've got to go grep through all my code to find 
 everywhere I've used a scope BufferedFile.  :-(

I'm actually very surprised that BufferedFile doesn't have a dtor which flushes and then closes its file. File's dtor closes itself.

It's a bit annoying, yeah. I think it's because the member object might already be deleted when the containing object's destructor gets called. Can't remember the exact reason for this limitation, but I think it's documented somewhere.

Exactly. The GC can't guarantee any particular order of destruction so members may be destroyed before their parents. So basically BufferedFile cannot try to refer to it's File member in the destructor. This is why we need some way to distinguish between deterministic destruction and regular gc-drived destruction as per Daniel's suggestion. Another suggestion made previously was to give the dtor an argument that indicated whether it was a deterministic destruction or not. --bb
Sep 22 2007
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Janice Caron wrote:
 On 9/22/07, Bill Baxter <dnewsgroup billbaxter.com> wrote:
 Exactly.  The GC can't guarantee any particular order of destruction so
 members may be destroyed before their parents.
 So basically BufferedFile cannot try to refer to it's File member in the
 destructor.

 This is why we need some way to distinguish between deterministic
 destruction and regular gc-drived destruction as per Daniel's
 suggestion.  Another suggestion made previously was to give the dtor an
 argument that indicated whether it was a deterministic destruction or not.

I'd vote for scope ~this() { /* for scope objects, called when the object goes out of scope */ }

Actually, to be of *real* use, it should be called for scope objects when they go out of scope *and* for general GC'ed objects if you explicitly call "delete" on them. Or, perhaps: lazy ~this() { // Invoked when the object is GC'ed } ~this() { // Invoked when the object is deterministically destroyed somehow } Or, again, as Bill mentioned, there have been requests before to add this: this(bool collected) { // collected is true iif the object has been GC'ed } -- Daniel
Sep 22 2007
prev sibling parent "Martin Fuchs" <martin-fuchs gmx.net> writes:
 Ex:
 char[][] lines;
 ...
 {
     scope Stream file = new BufferedFile("sample.txt",FileMode.Out);
     foreach(line; lines) {
        file.writefln(line);
     }
 }

Wait a minute, can anyone confirm that it's ok to use a scope BufferedFile without explicitly closing? BufferedFile contiains a 'new File()', but no destructor. The File's destructor contains a close(), however. So will the member File's destructor get called when the scope BufferedFile goes out of scope? It's really just a question of how scope works w.r.t classes with heap allocated members. Do the reference members get deleted deterministically on scope exit too? --bb

This should be the correct solution to automatically close the file used in a BufferedFile stream when leaving the function: char[][] lines; ... { scope File file = new File("sample.txt", FileMode.Out); Stream out = new BufferedFile(file); foreach(line; lines) { file.writefln(line); } } Regards, Martin
Sep 22 2007
prev sibling next sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 9/22/07, Bill Baxter <dnewsgroup billbaxter.com> wrote:
 Exactly.  The GC can't guarantee any particular order of destruction so
 members may be destroyed before their parents.
 So basically BufferedFile cannot try to refer to it's File member in the
 destructor.

 This is why we need some way to distinguish between deterministic
 destruction and regular gc-drived destruction as per Daniel's
 suggestion.  Another suggestion made previously was to give the dtor an
 argument that indicated whether it was a deterministic destruction or not.

I'd vote for scope ~this() { /* for scope objects, called when the object goes out of scope */ }
Sep 22 2007
prev sibling parent "Janice Caron" <caron800 googlemail.com> writes:
On 9/22/07, Bill Baxter <dnewsgroup billbaxter.com> wrote:
 Exactly.  The GC can't guarantee any particular order of destruction so
 members may be destroyed before their parents.
 So basically BufferedFile cannot try to refer to it's File member in the
 destructor.

So in general, that means that no destructor of any class, may refer to any member variables which are of reference type? This kinda brings us back to red code green code again, doesn't it? One could imagine a syntax in which any class member function which does not refer to any reference-type variables should be flagged as "green", and then it could be a compile error for a green function to refer to any reference-type variables, or to call a function which is not flagged green. So then we could enforce green-correctness as well as const-correctness. Oh, and greenness should be transitive (NOTE: I am /not/ really suggesting this). I have to ask though, can non-deterministic destructors actually do /anything/ useful? That is to say, if classes which needed to be explicitly closed all had an explicit close() function (or scope ~this() or whatever), which was allowed to call "red" code to do proper cleanup, what would be left for the regular destructor to do? And conversely, if the class didn't need an explicit close(), then why would you need a destructor anyway? It's confusing.
Sep 23 2007