c - 当替换的大小与原始文件相同时,修改文件是否安全
问题描述
我想做一些类似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
这是否会更快!
解决方案
这取决于您所说的“安全”是什么意思。与使用临时文件和rename
完成后在旧文件之上的原子性不同,此操作没有原子性;其他进程可以看到文件处于中间的、部分修改的状态。而且商店之间没有任何订单;他们可以在看到替换的开始之前看到替换的结束,或者以任何其他可以想象的顺序看到它们,如果还使用和不使用任何内存屏障,甚至可能以不一致的顺序看到它们。mmap
请注意, ; 真的没有什么特别之处mmap
。你也可以做同样的事情write
。
如果这些都不构成您的“不安全”,那么操作是完全安全的。特别是它不会截断文件或类似的东西。
推荐阅读
- reactjs - react-dom 17.0.0更新错误TypeError:init不是函数
- python - 如何分块加载yaml文件?
- reactjs - React 钩子无法从状态中获取价值
- typescript - 带有 Typescript 和样式化组件的 RN FlatList
- laravel - 带有模型属性绑定的 Livewire 简单下拉和保存按钮
- sql - T-SQL 中递归 CTE 的性能缓慢
- android - 如何输出日期时间和偏移量
- uwp - 如何防止 UWP 应用中虚拟键盘的恶意操作
- python - 如何为每次登录打开新的 selenium 会话?
- javascript - 显示变化描述时,Woocomerce 隐藏父描述