当替换文件与原始文件大小相同时,就地修改文件是否安全

Is it safe to modify file in place when replacement is same size as original

我想做类似于sed -i 's/abc/def/' file的事情 但没有临时文件。在我的例子中,匹配和替换的长度 相同 ;以下是否安全:

fd = open(file, O_RDWR);
fstat(fd, &sbuf);
mm = mmap(0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
i = 0;
while (i < sbuf.st_size) {
   memcpy(tmpbuf, mm + i, BUFSIZ);  // read from mem to tmpbuf (BUFSIZ at a time)
   if ((p = strstr(tmpbuf, needle))) { // match found
     memcpy(mm + i + (p - tmpbuf), replace, strlen(replace)); // strlen(replace) == strlen(needle)
   }
   i += BUFSIZ;
}
munmap(mm, sbuf.st_size);
fsync(fd);
close(fd);

(为简洁起见省略错误处理)

此外,不确定 mmap 是否使它更快!

这取决于你所说的 "safe" 是什么意思。与在完成后使用临时文件和原子 rename 覆盖旧文件不同,此操​​作没有原子性;其他进程可以看到处于中间、部分修改状态的文件。此外,商店之间没有任何订购;他们可以在看到替换的开头之前看到替换的结尾,或者以任何其他可以想到的顺序查看它们,如果还使用 mmap 和,甚至可能以 不一致的 的顺序查看不使用任何内存屏障。请注意 mmap; 并没有什么特别之处。你也可以用 write 做同样的事情。

如果其中none对你构成"unsafety",那么手术是完全安全的。特别是它不会截断文件或类似的东西。