当替换文件与原始文件大小相同时,就地修改文件是否安全
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",那么手术是完全安全的。特别是它不会截断文件或类似的东西。
我想做类似于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",那么手术是完全安全的。特别是它不会截断文件或类似的东西。