【问题标题】:Reading a file after being notified of changes brings old values在收到更改通知后读取文件会带来旧值
【发布时间】:2013-07-17 22:18:05
【问题描述】:

我在使用 Inotify 时遇到了一点问题。我正在查看配置文件,希望在修改时重新加载配置。检测到修改没有问题,但是当我读取配置值时,我得到了旧值。假设我有

attrib=value 

我修改了它,所以它是

attrib =value1

然后,当我再次读取文件时,我会得到“value”而不是“value1”。如果我再次修改属性,阅读时我会得到“value1”。

编辑:PATH_FLDR_CONFIG 指向文件本身。

代码如下:

int length, i = 0;
    int inotify;
    char buffer[EVENT_BUF_LEN];

    if((inotify = inotify_init())<0){
        pthread_exit(NULL);
    }

    inotify_add_watch( inotify, PATH_FLDR_CONFIG , IN_MODIFY );

    while (true){
        i=0;
        length = read( inotify, buffer, EVENT_BUF_LEN );
        if (length<0) continue;

        while ( i < length ) {
            read( inotify, buffer, EVENT_BUF_LEN );
            struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
            if ( event->mask & IN_MODIFY ) {
                    readConfigFile();
                }
            i += EVENT_SIZE + event->len;
          }

    }

在 readConfigFile() 里面我做了一个 configCreate + 各种读取;

t_config *config_create(char *path) {
    t_config *config = malloc(sizeof(t_config));

    config->path = strdup(path);
    config->properties = dictionary_create();

    struct stat stat_file;
    stat(path, &stat_file);
    FILE* file = NULL;

    file = fopen(path, "r");

    if (file != NULL) {
        char* buffer = calloc(1, stat_file.st_size + 1);
        fread(buffer, stat_file.st_size, 1, file);

        char** lines = string_split(buffer, "\n");

        void add_cofiguration(char *line) {
            if (!string_starts_with(line, "#")) {
                char** keyAndValue = string_split(line, "=");
                dictionary_put(config->properties, keyAndValue[0], keyAndValue[1]);
                free(keyAndValue[0]);
                free(keyAndValue);
            }
        }
        string_iterate_lines(lines, add_cofiguration);
        string_iterate_lines(lines, (void*) free);

        free(lines);
        free(buffer);
        fclose(file);
    }

    return config;
}

char *config_get_string_value(t_config *self, char *key) {
    return dictionary_get(self->properties, key);
}

【问题讨论】:

    标签: c inotify


    【解决方案1】:

    我不确定,但我认为值得检查您的 MODIFY 通知是发生在您的配置文件还是其他文件上。

    许多编辑器通过首先写入临时文件来对文件进行更改。例如,如果你的文件被命名为config.txt,它可能会被写入.config.txt.new#1234,然后将.config.txt.new#1234重命名为config.txt

    由于 inotify 位于一个目录上,它可能会看到临时文件的创建和修改,触发通知,您的程序会读取配置,然后才能被新文件替换。

    另一个可能的问题是,只要在文件上调用 write() 就会发生 MODIFY 事件。如果文件是在多次写入调用中写入的,您的程序可能会在配置文件完全写入之前打开并读取它。从您的示例中,配置字典可能包含旧值,如果它们没有被新值覆盖。

    尝试使用 CLOSE_WRITE 代替 MODIFY 事件。

    【讨论】:

    • 对不起,我没有指定它,但我看到了类似的答案,所以我更改了路径,使其指向文件。
    • @user1569740:我添加了另一个可能的解决方案。
    猜你喜欢
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多