Create an empty file in Node.js? - node.js

For now I use
fs.openSync(filepath, 'a')
But it's a little tricky. Is there a 'standard' way to create an empty file in Node.js?

If you want to force the file to be empty then you want to use the 'w' flag instead:
var fd = fs.openSync(filepath, 'w');
That will truncate the file if it exists and create it if it doesn't.
Wrap it in an fs.closeSync call if you don't need the file descriptor it returns.
fs.closeSync(fs.openSync(filepath, 'w'));

Here's the async way, using "wx" so it fails on existing files.
var fs = require("fs");
fs.open(path, "wx", function (err, fd) {
// handle error
fs.close(fd, function (err) {
// handle error
});
});

If you want it to be just like the UNIX touch I would use what you have fs.openSync(filepath, 'a') otherwise the 'w' will overwrite the file if it already exists and 'wx' will fail if it already exists. But you want to update the file's mtime, so use 'a' and append nothing.

Related

How to delete lines of text from file with createWriteStream with Node.js?

I'm trying to update a huge text document by deleting text that is dynamically received from an array. I cannot use readFileSync because the file is way too large so I have to stream it. The problem im encountering is the function deletes everything instead of only deleting what's in the array. Perhaps im not understanding how to properly delete something from a stream. How can this be done?
largeFile_example.txt
test_domain_1
test_domain_2
test_domain_3
test_domain_4
test_domain_5
test_domain_6
test_domain_7
test_domain_8
test_domain_9
test_domain_10
stream.js
const es = require('event-stream');
const fs = require('fs');
//array of domains to delete
var domains = ['test_domain_2','test_domain_6','test_domain_8'];
//loop
domains.forEach(function(domain){
//domain to delete
var dom_to_delete = domain;
//stream
var s = fs
.createReadStream('largeFile_example.txt')
.pipe(es.split())
.pipe(
es
.mapSync(function(line) {
//check if found in text
if(line === dom_to_delete){
//delete
var newValue = dom_to_delete.replace(line, '');
fs.createWriteStream('largeFile_example.txt', newValue, 'utf-8');
}
})
.on('error', function(err) {
console.log('Error while reading file.', err);
})
.on('end', function() {
//...do something
}),
);
})
You can simply use readline interface with the streams and you can read line by line. When you encounter any domain from the array just don't add it.
You can use for-of with async/await
const fs = require('fs');
const readline = require('readline');
async function processLine() {
const fileStream = fs.createReadStream('yourfile');
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
// Note: crlfDelay recognize all instances of CR LF
// ('\r\n') in file as a single line break.
for await (const line of rl) {
// each line will be here as domain
// create a write stream and append it to the file
// line by line using { flag: a }
}
}
processLine();
To delete the domains from the existing file, you need to follow these steps:
Need to read the file as a stream.
Replace the text you don't want with the '' using regex or replace method.
add the updated content to the temp file or a new file.
There is no way you can read from one point and update the same line. I mean I am not aware of such a technique in Node.js(will be happy to know that). So that's why you need to create a new file and once updated remove the old file.
Maybe you can add some more value to how you code it as I am not sure why you want to do that. If your file is not large you can do that in-place, but your case is different.

Node JS: What's the difference Between open file in write mode and write mode

I know that write mode can write things but what does open() in write mode do?
var fs = require('fs');
fs.open('mynewfile2.txt', 'w', function (err, file) {
if (err) throw err;
console.log('Saved!');
});
File open with w flag refers to:-
Open file for writing. The file is created (if it does not exist) or
truncated (if it exists).
For more information please refer Link

Node.js transform file stream and write to same file results in empty file

I am trying to modify some files using node file streams and custom transform function. This is the transform function:
const TransformStream = function() {
Transform.call(this, {objectMode: true});
};
util.inherits(TransformStream, Transform);
TransformStream.prototype._transform = function(chunk, encoding, callback) {
let line = chunk.toString()
if (!this.findLinesMode && lineStartRe.test(line)) {
this.findLinesMode = true
this.lines = []
}
if (this.findLinesMode) {
this.lines.push(line)
}
if (this.findLinesMode && lineEndRe.test(line)) {
this.findLinesMode = false
line = this.lines.join('').replace(re, (str, match) => match.trim())
}
if (!this.findLinesMode) {
this.push(line + '\n')
}
callback()
};
And I tried to use it in the following code:
byline(fs.createReadStream(filePath, {encoding: 'utf8'}))
.pipe(new TransformStream())
.pipe(fs.createWriteStream(filePath))
However, the file ends up empty.
I am confident that the transformer code works as expected, because I tried pipe it to process.stdout and the output is exactly how I want it.
My question is: What I am doing wrong and what can I try to fix it?
This is not a problem with your transformer code but a problem that you open a file for writing that you overwrite probably before you even read anything from it.
It would be the same in shell. If you run:
cat < file.txt > file.txt
or:
tr a-z A-Z < x.txt > x.txt
it will result in making the file empty.
You have to pipe to a temporary file and then substitute the old file with the new one. Or alternatively rename the old one to some other temporary name, open the new file under the correct name and pipe the renamed file to the old file, making your transforms on the way.
Make sure to use a secure way to make a name of the temporary file. You can use modules like:
https://www.npmjs.com/package/tmp
https://www.npmjs.com/package/temp
https://www.npmjs.com/package/tempfile

Update a file only if it exists Node

I want to update a file using NodeJs only if the file exists.
How to do that.
I read the node docs and fs.exists is deprecated.
If I use fs.writeFile directly it will create a new file if one doesn't exist.
How to update a file only if it exists.
Thanks.
use fs.open and fs.write.
fs.open flags you need:
* 'r+' - Open file for reading and writing. An exception occurs if the file does not exist.
From NodeJs 4.x documentation
var fs = require('fs');
fs.access('/path/to/your/file', fs.F_OK, (err) => {
if (!err) {
// File exists, update your file
}
});
fs.F_OK - File is visible to the calling process. This is useful for determining if a file exists, but says nothing about rwx permissions. Default if no mode is specified.
You can also use the flags fs.R_OK | fs.W_OK | fs.X_OK to additionally check the rwx permissions of the calling process.
Try this:
var fs = require('fs');
var myFile = './mono.txt';
try {
if (!fs.accessSync(myFile)) console.log('File does already exist');
}
catch (exc) {
fs.writeFile(myFile);
}

In node.js why i'm not getting error while trying to write the non existing file

In the below code,i'm trying to write the non existing file 'doesnotexist.text' but still i'm getting the result as success.
var fs = require('fs');
fs.writeFile('doesnotexist.text', 'Hello World!', function (err) {
if (err) {
console.log('error is '+err);
return;
}
else{
console.log('success.');
}
});
Because the writeFile function creates the file if it does not exist.
Basically, you can change the behavior of this function by submitting an options object as third parameter, as described in the documentation. For the flags property you can provide any value from the ones described in the documentation for fs.open.
For write, they are:
w - Open file for writing. The file is created (if it does not exist) or truncated (if it exists).
wx - Like w but opens the file in exclusive mode.
w+ - Open file for reading and writing. The file is created (if it does not exist) or truncated (if it exists).
wx+ - Like w+ but opens the file in exclusive mode.
The default value for writeFile is w, hence the file is created if it does not exist. As there is no option that provides an error when the file does not exist, you need an additional check whether the file already exists.
For this, check out the fs.exists function (see documentation for details).
Basically, your code should somewhat like this:
var fs = require('fs');
fs.exists('foo.txt', function (exists) {
if (!exists) {
return 'Error, file foo.txt does not exist!';
}
fs.writeFile('foo.txt', ...);
});

Resources