Reputation: 131
I need to check for the existence of a file before executing fs.writeFile
, so if the file already exists, fs.writeFile
sould not replace the file. But the documentation says the following :
Using
fs.stat()
to check for the existence of a file before callingfs.open()
,fs.readFile()
orfs.writeFile()
is not recommended. Instead, user code should open/read/write the file directly and handle the error raised if the file is not available.
If I call fs.writeFile
directly, the function will replace the file if it already exists, and the error
variable will be null
.
I want to ignore the call to fs.writeFile
if the file already exists.
Thanks.
Upvotes: 0
Views: 1039
Reputation: 707446
Robert has the correct answer (just pass in the appropriate flags fs.writeFile(fname, data, { flag : 'wx' }, ...)
), but I thought I would explain why it is not recommended to use fs.stat()
followed by fs.writeFile()
. When you do something like this:
fs.stat(fname, function(err) {
if (err) {
// in the bit of time right here, there is a race condition
fs.writeFile(fname, data, function(err) {
// file written
});
}
});
There is a race condition. In any sort of multi-process system or any sort of file system shared with other systems, there can be a situation where fs.stat()
reports the file is not there, but between that moment and the time that you actually call fs.writeFile()
, some other process or thread or computer writes that file and now you've just overwritten an existing file which is something you did not want to do. So, this is simply not reliable in some circumstances and thus is not recommended.
What you need instead is an atomic operation that will both check if it's there and, if not, will create it for you. That will give you a reliable system so that the file will never be accidentally overwritten.
By passing the wx
flags to fs.writeFile()
, you tell the underlying OS to write these bytes to the file only if the file doesn't already exist and it will be done in an atomic fashion that does not have multi-thread/process/computer race conditions.
There are limits to the race condition and there are situations where your system would not actually be subject to it (only one node.js process that can ever write to that file), but it is simply safer to just always code in the safe way, no matter what and, in fact, the safe way is less code too.
Upvotes: 2
Reputation: 203359
I want to ignore the call to
fs.writeFile
if the file already exists.
Use the wx
flag (documented here):
wx
- Like'w'
but fails if path exists.
fs.writeFile('/path/to/file', data, { flag : 'wx' }, function(err) {
if (err && err.code === 'EEXIST') {
console.log('file already exists, not overwriting');
return;
}
...
})
EDIT: the reason it's not recommended to use fs.stat
before fs.open/fs.writeFile/fs.readFile
is because of an inherent race condition: in between the calls to fs.stat
and (say) fs.writeFile
, there's a small window of time in which a file could get created, even though it didn't yet exist when fs.stat
was called. So there would still be a chance that fs.writeFile
could overwrite an existing file.
If you use file flags, the check for existence is done atomically.
Upvotes: 2