节点js:fs.rename覆盖文件,如果已经存在
fs.rename是否覆盖文件,如果它已经存在?
var fs = require('fs'), oldPath = 'firstfile.txt', newPath = 'temp/firstfile.txt'; fs.rename(oldPath, newPath, function (err) { console.log('rename callback ', err); });
如果“/newFolder/somefile.txt”存在,会发生什么情况?
简短的回答: 是的
很长的回答:
我创build了一个脚本来检查它:
var fs = require('fs');
创build两个文件:
fs.writeFileSync('a.txt',"This is a file") fs.writeFileSync('b.txt',"This is another file")
改名:
fs.renameSync('a.txt','b.txt');
检查是否被覆盖:
var text = fs.readFileSync('b.txt', "utf-8"); console.log(text) // This is a file
看起来像fr.rename提供了与Linux rename(2)命令提供的function相同的function(来源: 在ExpressJS / NodeJS中移动文件 )。 话虽如此,如果您查看Linux rename(2)命令的文档,他们会说如果您正在重命名的文件名已经存在,那么现有的文件名将被replace并覆盖(来源: http:// linux。 die.net/man/2/rename )
nodejs的fs.rename()
覆盖了文件,因为这是Unix rename()
定义的方式,而fs.rename()
被logging为包装rename()
Unix syscall。 我不知道在nodejs文档中的任何地方,直接说明这与fs.rename()
。 但是,有几件事要注意让我们确定这一点:
-
在描述
fs.rename
的function时 ,nodejs文档链接到Linux手册页以rename(2)
。 文档的GitHub固定链接不链接,但处理器会自动将rename(2)
rename(2)
。 -
文档的“系统调用和手册页”部分指出,系统调用在Windows上模拟unix行为。 我从“在Windows上replaceUnix系统调用语义有时是不可能的”这个推断,这意味着在可能的情况下nodejs在Windows上实现了Unix语义 :
大多数Unix系统调用都具有与Windows相同的function,但是相对于Linux和MacOS,Windows的行为可能会有所不同。 有关在Windows上更换Unix系统调用语义的细微方法的示例,请参阅节点问题4760 。
-
我已经看到了关于这种事情的其他讨论,人们总是提到nodejs是如何使用libuv来处理事情的,所以我们只需要看看libuv。 libuv的目标是提供一个可移植的POSIX APIasynchronous实现,因此它的目标之一就是即使在Windows上也像unix一样运行。 libuv文档似乎没有详细讨论
rename()
,但fs__rename()
的Windows实现 使用MOVEFILE_REPLACE_EXISTING
调用MoveFileEx()
。 -
哦,我差点忘了。 即使您知道nodejs将
fs.rename()
定义为POSIXrename()
,也许您不知道POSIX定义的有关覆盖的行为rename()
:如果存在由新参数命名的链接,则该链接将被删除, 旧的名称将重命名为新的 。 在这种情况下,一个名为new的链接在整个重命名操作中对其他线程都是可见的,并且在操作开始之前引用new或old引用的文件。
简单地说,如果重命名的目标已经存在,这就描述了事务性文件replace。 如果在调用
rename()
之前已经存在一个具有新名字的文件,它将永远不会停止存在 – 即使程序崩溃或者电源掉电了。 在某个时间点,新名称将开始引用具有旧名称的文件。您应该更喜欢这种方法来删除原始文件,然后重新命名新创build的文件,因为那么新path中的文件将暂时停止存在(可能导致尝试打开它的某个竞争条件),或者如果进程被终止或者在合适的时间发生电力故障,永久性的。
注意:由于可移植性问题,当您希望代码也适用于Windows用户时,考虑使用像graceful-fs
这样的可移植助手和cross-spawn
是很好的做法。 我意识到这不是提问者的问题,但是我推断提问者只会提出这样一个问题,因为win32背景下重命名不能覆盖文件,或者因为只有在对Unix以外的可移植性感兴趣时才会问这样的问题。