Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

node js: does fs.rename overwrite file if already exists

Does fs.rename overwrite the file if it already exists?

var fs = require('fs'),
    oldPath = 'firstfile.txt',
    newPath = 'temp/firstfile.txt';

fs.rename(oldPath, newPath, function (err) {
    console.log('rename callback ', err); 
});

What happens if '/newFolder/somefile.txt' aready exists ?

like image 322
yar1 Avatar asked Jan 19 '14 15:01

yar1


People also ask

Does fs write file overwrite?

writeFileSync and fs. writeFile both overwrite the file by default. Therefore, we don't have to add any extra checks.

What does fs rename do?

The fs. rename() method is used to asynchronously rename a file at the given old path to a given new path. It will overwrite the destination file if it already exists.

What does fs do in node JS?

Node. js includes fs module to access physical file system. The fs module is responsible for all the asynchronous or synchronous file I/O operations. Let's see some of the common I/O operation examples using fs module.

How do I rename a file in node?

Node FS Rename File – To rename file with Node FS, use fs. rename(new_file_name, old_file_name, callback_function) for asynchronous file rename operation and use fs. renameSync(new_file_name, old_file_name) for synchronous file rename operation.


3 Answers

Short answer: yes


Long answer:

I created a script to check it:

var fs = require('fs');

Create two files:

fs.writeFileSync('a.txt',"This is a file")
fs.writeFileSync('b.txt',"This is another file")

Rename:

fs.renameSync('a.txt','b.txt');

Check if it was overriden:

var text = fs.readFileSync('b.txt', "utf-8");

console.log(text) // This is a file
like image 51
Ilan Frumer Avatar answered Oct 20 '22 11:10

Ilan Frumer


nodejs’s fs.rename() overwrites files because that is how the Unix rename() is defined and fs.rename() is documented as wrapping the rename() Unix syscall. I do not know of any place in the nodejs docs that directly states this regarding fs.rename(). However, there are a few things to note which let us determine this:

  1. The nodejs docs link to the Linux manpage for rename(2) when describing the functionality of fs.rename. The GitHub permalink of the docs does not linkify it, but the processer automatically turns rename(2) into rename(2).

  2. The “Syscalls and man pages” section of documentation states that syscalls emulate unix behavior on Windows. I infer this from the phrase “it’s sometimes impossible to replace Unix syscall semantics on Windows” which implies that nodejs has implemented Unix semantics on Windows when it is possible:

    Most Unix syscalls have Windows equivalents, but behavior may differ on Windows relative to Linux and macOS. For an example of the subtle ways in which it's sometimes impossible to replace Unix syscall semantics on Windows, see Node issue 4760.

  3. I’ve seen other discussions about things like this and people always refer to how nodejs just uses libuv for things so one should just look at libuv. libuv’s goal is to provide a portable asynchronous implementation of POSIX APIs and thus one of its goals is to behave like unix even on Windows. The libuv docs don’t seem to discuss rename() at length, but the Windows implementation of fs__rename() calls MoveFileEx() with MOVEFILE_REPLACE_EXISTING.

  4. Oh, and I almost forgot. Even if you know that nodejs defines fs.rename() as POSIX rename(), perhaps you don’t know the POSIX-defined behavior of rename() regarding overwriting:

    If the link named by the new argument exists, it shall be removed and old renamed to new. In this case, a link named new shall remain visible to other threads throughout the renaming operation and refer either to the file referred to by new or old before the operation began.

Simply, this describes a transactional file replacement if the target of the rename already exists. If a file with the new name already exists prior to calling rename(), it will never cease to exist—even if your program crashes or box loses power. At some point in time, the new name will start referring to the file with the old name.

You should prefer this method over removing the original file and then renaming the newly created one because then the file at the new path will cease to exist momentarily (possibly causing a race condition for something trying to open it) or, if the process is killed or a power failure happens at the right time, permanently.

Note: due to portability issues, it is good to consider using portability helpers like graceful-fs and cross-spawn when you want your code to also work for Windows users. I realize that is not the asker’s question, but I inferred that the asker would only ask such a question because of a win32 background where rename can’t overwrite files or because one would only ask a question such as this when interested in portability beyond Unix.

like image 30
binki Avatar answered Oct 20 '22 10:10

binki


It looks like the function fs.rename() provides the same functionality that the Linux rename(2) command provides (source: Move File in ExpressJS/NodeJS). Having said this, if you look at the docs for the Linux rename(2) command, they say that if the file name you are renaming to already exists, the existing file name will be replaced and overwritten (source: http://linux.die.net/man/2/rename)

like image 1
alex-ayala Avatar answered Oct 20 '22 11:10

alex-ayala