如何在不覆盖现有文件的情况下重命名文件?

How to rename file without overwriting existing?

假设我有两个文件:

/1.txt

/2.txt

现在如果我调用 fs.rename('/1.txt', '/2.txt'),它会将 2.txt 替换为 1.txt

他们说这就是重命名的工作原理 Linux 等等。但如果新路径上的文件已经存在,我不想替换。理想情况下,我想对此抛出一些错误,比如 EEXIST。据我所知,在重命名之前使用 fs.existsSyncfs.stat 或其他检查会引入竞争条件。

为避免竞争条件,您需要某种锁定机制。

在 Linux 系统上,使用锁定文件是非常标准的 - 通常它是一个空文件或目录,用于检查是否正在发生某些操作序列。类似于数据库 row/table 锁定文件的创建和删除是原子的 - 其余操作不是。

我会为此使用 proper-lockfile package and move from fs-extra

const lockfile = require('proper-lockfile');
const fs = require('fs-extra');

lockfile.lock('some/file')
  .then(() => fs.move('/tmp/file', 'some/file'))
  .finally(() => lockfile.unlock('some/file'));

另请注意,任何使用 some/file 的逻辑都必须遵守 lockfile,否则竞争条件仍然存在。