如何解决fs.renameSync 是一种抗损坏的原子操作吗?
const path = require('path');
const fs = require('fs');
const os = require('os');
const from_dir = path.resolve(os.homedir(),'./from_dir');
const to_dir= path.resolve(os.homedir(),'./new_dir');
fs.renameSync(from_dir,to_dir);
假设我在 NodeJS 应用程序中有以下代码片段,我的目标是将“from_dir”重命名为“to_dir”。根据我的理解,重命名操作应该是原子的。我是否也可以依靠此操作在重命名过程中永远不会破坏“from_dir”目录内容,即使该过程在此过程中被强行关闭?或者最好先将目录的内容复制到备份,然后尝试重命名(与 cp -r ~/from_dir ~/from_dir_backup
等效的名称)?我试图重现这样的场景,但无法做到。
解决方法
在幕后,rename
中的 renameSync
和 fs
函数调用了它们的低级对应函数:rename
系统调用。该系统调用仅更新指向目录 inode 的名称,但不会更改您正在移动的目录的内容。
您可以自己验证这一点:在开始时检查目录的 inode 编号(使用 stat
命令),执行 fs.renameSync
,然后检查目标的 inode 编号。它们是相同的,这意味着目录不是从头开始重新创建的,而是在内容完整的情况下重新命名。
现在,POSIX 不要求操作是原子的本身 - 事实上,Linux 联机帮助页 (man 2 rename
) 对原子性主题有这样的说法:
如果 newpath 已经存在,它将被原子替换,这样另一个尝试访问 newpath 的进程就不会发现它丢失了。但是,可能会出现一个窗口,其中 oldpath 和 newpath 都指向被重命名的文件。
我不确定这个极端情况(2 个链接)是否适用于目录,因为我从来没有能够创建超过 1 个指向目录的硬链接,但手册页似乎很令人放心,因为该目录是不会消失或被遗忘。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。