如何在不覆盖现有文件的情况下重命名文件?
How to rename file without overwriting existing?
假设我有两个文件:
/1.txt
/2.txt
现在如果我调用 fs.rename('/1.txt', '/2.txt')
,它会将 2.txt
替换为 1.txt
。
他们说这就是重命名的工作原理 Linux 等等。但如果新路径上的文件已经存在,我不想替换。理想情况下,我想对此抛出一些错误,比如 EEXIST
。据我所知,在重命名之前使用 fs.existsSync
、fs.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
,否则竞争条件仍然存在。
假设我有两个文件:
/1.txt
/2.txt
现在如果我调用 fs.rename('/1.txt', '/2.txt')
,它会将 2.txt
替换为 1.txt
。
他们说这就是重命名的工作原理 Linux 等等。但如果新路径上的文件已经存在,我不想替换。理想情况下,我想对此抛出一些错误,比如 EEXIST
。据我所知,在重命名之前使用 fs.existsSync
、fs.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
,否则竞争条件仍然存在。