On 03/19/2011 05:51 PM, Andrej Mitrovic wrote:
I'm trying to do something like the following:
File inputfile;
foreach (string name; dirEntries(r".\subdir\", SpanMode.shallow))
{
if (!(isFile(name)&& getExt(name) == "d"))
{
continue;
}
inputfile = File(name, "a+");
foreach (line; inputfile.byLine)
{
if (line == "import foo.d")
{
inputfile.write("import bar.d"); // or ideally `line = "import
bar.d"`
}
}
}
That obviously won't work. I think I might need to use the `fseek` function to
keep track of where I am in the file, or something like that. File I/O in D is
no fun..
The only problem with your approach that a "line" is an abstract
concept. In a filesystem, there are only blocks of bytes. When you write
(flush) a byte to a file, the file transaction is actually an entire
block at a time (ext3 defaults to a 4k block, for example.) Lines are
just an array of bytes. When dealing with (relatively) fast memory,
modifying a line is pretty transparent. If you open a 1GB file and add
bytes at the very beginning, the filesystem is quite likely to write out
the entire file again.
I would suggest you write out to a temporary file, and then move the
file on top of the original file.
foreach(name ...)
{
inputfile = File(name, "r");
outputfile = File("/tmp/" ~ name, "a");
foreach(line ...)
{
do something to line
outputfile.write(line);
}
outputfile.close();
rename("/tmp" ~ name, name);
}
This will allow you to manipulate line by line, but it won't be
in-place. This is the type of approach that a lot of text editors take,
and a very common work around. If you were to encounter a language that
allows you to read and write lines iteratively and in-place like this in
a file, I'll bet you they are writing your changes to a temp file, and
moving the file over the top of the original at the end (perhaps when
you close()).