C++ 写入文件,st#mtime不';不变
我有一个程序,想检查一个文件是否被修改。regtest失败,事实上,尽管文件已更改,C++ 写入文件,st#mtime不';不变,c++,c,linux,posix,C++,C,Linux,Posix,我有一个程序,想检查一个文件是否被修改。regtest失败,事实上,尽管文件已更改,st_mtime没有!此外,外部统计数据也证实了这一点 我相信Stu_mtime应该改变,因为统计数据(2)显示 字段st_mtime通过文件修改进行更改,例如,通过mknod(2)、truncate(2)、utime(2)和write(2)(大于零字节)进行更改 下面是一段C代码,说明了这一点: #include <assert.h> #include <stdio.h> #includ
st_mtime
没有!此外,外部统计数据也证实了这一点
我相信Stu_mtime应该改变,因为统计数据(2)显示
字段st_mtime通过文件修改进行更改,例如,通过mknod(2)、truncate(2)、utime(2)和write(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);
}
切勿在有副作用的函数上使用
断言
始终这样做:
FILE * fp;
fp = fopen(...);
assert(fp != NULL);
包含
assert()
的整行将从发布版本中消失。切勿在具有副作用的函数上使用assert
始终这样做:
FILE * fp;
fp = fopen(...);
assert(fp != NULL);
包含
assert()
的整行内容将从发布版本中消失。首先,我强烈建议您不要在assert
s中使用带有副作用的语句。我知道这很方便,如果代码永远不会投入生产,那也不重要,但它不是好的形式。特别是,如果您定义了NDEBUG
,那么断言将转换为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;
到
首先,我强烈建议您不要在assert
s中使用带有副作用的语句。我知道这很方便,如果代码永远不会投入生产,那也不重要,但它不是好的形式。特别是,如果您定义了NDEBUG
,那么断言将转换为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()进行更改。它只是“echo$1>/tmp/foo”的C等价物。查看shell中的文件,我确认它包含第二次更改的内容,但包含第一次更改的modtime!某些装载选项可能会影响索引节点内mtime的更新方式。@Basile-true,但在这种情况下,代码是错误的。但是,这些装载选项会在文件关闭时更新元数据。McKusick的BSD ffs早在20世纪80年代就意识到了这个问题,也就是说,每次物理写入更新元数据(如mtime)都会带来额外的开销,因为这意味着磁盘上会有一个额外的i/o。如何更改检查的文件?在分析代码之前,可能值得考虑该步骤中的错误。函数touch()进行更改。它只是“echo$1>/tmp/foo”的C等价物。查看shell中的文件,我确认它包含第二次更改的内容,但包含第一次更改的modtime!某些装载选项可能会影响索引节点内mtime的更新方式。@Basile-true,但在这种情况下,代码是错误的。但是,这些装载选项会在文件关闭时更新元数据。McKusick的BSD ffs早在20世纪80年代就意识到了这个问题,也就是说,每次物理写入更新元数据(如mtime)都会带来额外的开销,因为这意味着磁盘会有一个额外的i/o。嗯,是的,我是个白痴。谢谢你给我指出显而易见的。。。这是一个来自一些相当复杂的代码的人为例子,我清楚地校对了我认为我写的东西。而现实生活中更复杂的代码也有同样的错误。我比我梦想的更坚定。嗯,是的,我是个白痴。谢谢你给我指出显而易见的。。。这是一个来自一些相当复杂的代码的人为例子,我清楚地校对了我认为我写的东西。而现实生活中更复杂的代码也有同样的错误。我比我梦想的更坚定。同意,谢谢。在这个扔掉的例子中,它的意思是排除例子中错误的返回值。同意,谢谢。在这个扔掉的示例中,它意味着排除示例中错误的返回值。