std.file vs std.stream
Lars T. Kyllingstad
public at kyllingen.NOSPAMnet
Thu Mar 4 06:51:21 PST 2010
Ludovic A. wrote:
> I am trying to write a simple file parser in D2. Following examples I found 2
> working ways to read a line and print it:
Where did you find the examples? They seem pretty out-of-date.
> import std.stream
> Stream file = new BufferedFile(filename);
> foreach(char line; file)
> writefln("line: %s",line);
> import std.file;
> File* file = new File(filename);
> while (!file.eof())
> writef("%s", file.readln());
> My question from there is what is the difference between opening a stream and
> a file _in this case_, and what is the most appropriate in this case?
Did you really mean 'import std.file' up there, or did you mean 'import
std.stdio' -- because that's where the File type is defined.
What you're seeing here is actually a consequence of Phobos very much
being a work-in-progress. std.stdio was completely rewritten about a
year ago, and it most likely contains what you're looking for.
std.stream, on the other hand, hasn't seen major updates since 2005 or
so, and is most likely an old left-over from D1. I suspect it will be
removed soon, or at least completely rewritten to adhere to the range
So, my advice is to use std.stdio.File, and to use it like this:
auto file = File(filename);
foreach (line; file.byLine)
Two things one should be aware of with the above example:
1. File is a struct, not a class, which is why I didn't 'new' it.
However, under the hood it works as a reference type, does its
own reference counting, and will close the file *immediately*
when there are no more references to it (i.e. the last copy of
'file' goes out of scope).
2. file.byLine returns a range that iterates over the lines of the
file. The 'line' variable is a char because the buffer is
reused for each iteration, whereas the string type is immutable.
Thus, if you want to store the contents of the 'line' array
somewhere you need to copy it.
The std.stdio docs (with a few examples) can be found here:
> Also in the foreach I can not write foreach (string line, file) but I have to
> use char. Is there a way to go around this?
> Finally I can not use foreach in the std.file example, because the compiler
> says "foreach: File* is not an aggregate type". I was surprised that foreach
> worked on a Stream at the first place, so no big deal :) But what do we have
> under the hood? How can it work for Stream and not for File? Is the limitation
> coming from the foreach implementation?
I'm beginning to suspect you are using an ancient version of DMD2. Am I
More information about the Digitalmars-d-learn