查找并替换文件中的一行

时间:2018-07-23 21:59:55

标签: file d stdio seek

我的目标是逐行搜索文件,直到找到varName = varValue格式的变量声明。计数到该行开头的字节,然后用相同的varName替换该行,但是使用新的值。

这是一个非常简单的配置文件处理程序,我从头开始编写它以避免任何依赖性。我这样做的原因不仅是转储string[string]关联数组,还因为我想保留注释。我还希望避免将整个文件读入内存,因为它可能会变大。

这是我编写的代码,但是使用setVariable时什么也没发生,并且文件保持不变。

import std.stdio: File;
import std.string: indexOf, strip, stripRight, split, startsWith;
import std.range: enumerate;

ptrdiff_t getVarPosition(File configFile, const string varName) {
    size_t countedBytes = 0;

    foreach (line, text; configFile.byLine().enumerate(1)) {
        if (text.strip().startsWith(varName))
            return countedBytes;

        countedBytes += text.length;
    }

    return -1;
}

void setVariable(File configFile, const string varName, const string varValue) {
    ptrdiff_t varPosition = getVarPosition(configFile, varName);

    if (varPosition == -1)
        return; // For now, just return. This variable doesn't exist.
        // Will handle this later, it needs to append to the bottom of the file.

    configFile.seek(varPosition);
    configFile.write(varName ~ " = " ~ varValue);
}

1 个答案:

答案 0 :(得分:0)

您的代码丢失了一些部分,这使诊断变得困难。最重要的问题可能是“如何打开配置文件?”。这段代码符合我的期望:

unittest {
    auto f = File("foo.txt", "r+");
    setVariable(f, "var3", "foo");
    f.flush();
}

也就是说,它找到以“ var3”开头的行,并用新值替换文件的一部分。但是,您的getVarPosition函数不计算换行符,因此偏移量是错误的。另外,请考虑新的varValue与旧值的长度不同时会发生什么。如果您拥有“ var = hello world”,并调用setVariable(f, "var", "bye"),则最终将得到“ var = byelo world”。如果它长于现有值,它将覆盖下一个变量。