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()).

Reply via email to