【问题标题】:Find and replace a line in a file查找和替换文件中的一行
【发布时间】:2018-07-23 21:59:55
【问题描述】:

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

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

这是我写的代码,但没有任何反应,使用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);
}

【问题讨论】:

  • 尝试最小化您的代码以解决问题。我不确定你的实际问题是什么。 readConfig 真的依赖于这个问题吗? File configFile 在哪里打开?显示一个示例配置文件并添加 main 函数,该函数将显示它是如何不工作的。 (顺便说一句,您正在创建一个依赖项,它只是第一方依赖项:) 那么,没有第三方库大小或许可的优势是什么? :) )

标签: file d stdio seek


【解决方案1】:

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

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”。如果它比现有值长,它将覆盖下一个变量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 2011-04-25
    • 2011-10-27
    • 2021-04-27
    • 2012-09-08
    • 2011-07-18
    相关资源
    最近更新 更多