我想做与sed -i 's/abc/def/' file
类似的操作但没有临时文件。在我的情况下,匹配和替换的长度为[[same;以下是安全的:
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
是否可以使速度更快!
rename
不同,此操作没有原子性。其他进程可能会看到文件处于中间,部分修改的状态。而且,商店之间没有任何订购;他们可以在看到替换的开始之前就看到替换的结束,或者可以以任何其他可能的顺序看到替换,如果也使用mmap
而不使用任何内存屏障,则可能以inconsistent替换。注意,mmap
确实没有什么特别的。您也可以使用write
做同样的事情。