我有一个程序想要检查一个文件是否已被修改。回归测试失败,实际上,尽管文件已经更改,但st_mtime没有!此外,外部统计数据也证实了这一点。
我认为st_mtime应该改变,因为stat(2)说
字段st_mtime是通过文件修改来更改的,例如,由mknod(2)、截断(2)、utime(2)和写(2)(大于零字节)来更改。
这里有一些C代码说明了这一点:
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void touch(const char *fn, const char *contents)
{
FILE *fp;
assert(fp = fopen(fn, "w"));
fprintf(fp, contents);
fclose(fp);
}
int main( int argc, char *argv[] )
{
struct stat st;
char path[] = "/tmp/foo";
time_t m1, m2;
unsigned int t;
touch(path, "hello\n");
assert(!stat(path, &st));
m1 = st.st_mtime;
touch(path, "hello, world!\n");
t = sleep(2);
assert(!stat(path, &st));
m2 = st.st_mtime;
printf("Sleep remaining: %lu\n", t);
printf("Elapsed modtime=%lu\n", m2 - m1);
}以下是一些可以用来确认它不仅仅是C程序中缓存的bash:
$ while true;做stat /tmp/foo \ grep修改;睡眠1;完成
有什么建议吗?Fwiw,这是在这样确定的一个系统上运行的:
jeff@london:src $ uname -a
Linux london 2.6.32-37-generic #81-Ubuntu SMP Fri Dec 2 20:32:42 UTC 2011 x86_64 GNU/Linux
jeff@london:src $ 发布于 2012-01-05 21:03:00
首先,我强烈建议您不要在assert中使用有副作用的语句。我知道这很方便,如果代码永远不会产生效果,这并不重要,但它不是好的形式。特别是,如果您定义了NDEBUG,则assert的代码将被转换为noop,条件的代码永远不会执行。
现在,问题很可能是将sleep调用放在两个touch调用之后,而不是在它们之间。改变这一点:
touch(path, "hello\n");
assert(!stat(path, &st));
m1 = st.st_mtime;
touch(path, "hello, world!\n");
t = sleep(2);
assert(!stat(path, &st));
m2 = st.st_mtime;至
touch(path, "hello\n");
int rv = stat(path, &st);
assert(!rv);
m1 = st.st_mtime;
t = sleep(2);
touch(path, "hello, world!\n");
int rv = stat(path, &st);
assert(!rv);
m2 = st.st_mtime;发布于 2012-01-05 21:02:44
在有副作用的函数上,assert永远不会使用!
总是这样做:
FILE * fp;
fp = fopen(...);
assert(fp != NULL);包含assert()的整个行从发行版构建中消失。
https://stackoverflow.com/questions/8749543
复制相似问题