How to read file character by character with Node.js - node.js

I know you can read line-by-line with require('readline'), is there a good way to read a file character by character? Perhaps just use readline and then split the line into characters?
I am trying to convert this code:
const fs = require('fs');
const lines = String(fs.readFileSync(x));
for(const c of lines){
// do what I wanna do with the c
}
looking to make this into something like:
fs.createReadStream().pipe(readCharByChar).on('char', c => {
// do what I wanna do with the c
});

Simple for loop
let data = fs.readFileSync('filepath', 'utf-8');
for (const ch of data){
console.log(ch
}
Using forEach
let data = fs.readFileSync('filepath', 'utf-8');
data.split('').forEach(ch => console.log(ch)

Related

Apply regex to .txt file node.js

I'm trying to escape quotes in txt file using node.js and regex.
My code looks like this:
const fs = require("fs");
const utf8 = require("utf8");
var dirname = ".\\f\\";
const regex = new RegExp(`(?<=".*)"(?=.*"$)`, "gm");
fs.readFile(dirname + "test.txt", (error, data) => {
if (error) {
throw error;
}
var d = data.toString();
d = utf8.encode(d)
console.log(`File: ${typeof d}`); //string
// d = `Another string\n"Test "here"."\n"Another "here"."\n"And last one here."`;
console.log(`Text: ${typeof d}`); //string
var re = d.replace(regex, '\\"');
console.log(`Result:\n${re}`);
/* Another string
"Test \"here\"."
"Another \"here\"."
"And last one here."
*/
});
The problem is:
When I remove comment from the line, everything works fine. But if i read the text from the file it doesn't want to work.
Thanks for any comments on this.
Well.. turns out the problem was in file encoding. The file was encoded in UTF-16, not in UTF-8. Node.js wasn't giving me any signs of wrong encoding, so well, nice.

Reading file using Node.js "Invalid Encoding" Error

I am creating an application with Node.js and I am trying to read a file called "datalog.txt." I use the "append" function to write to the file:
//Appends buffer data to a given file
function append(filename, buffer) {
let fd = fs.openSync(filename, 'a+');
fs.writeSync(fd, str2ab(buffer));
fs.closeSync(fd);
}
//Converts string to buffer
function str2ab(str) {
var buf = new ArrayBuffer(str.length*2); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i=0, strLen=str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
append("datalog.txt","12345");
This seems to work great. However, now I want to use fs.readFileSync to read from the file. I tried using this:
const data = fs.readFileSync('datalog.txt', 'utf16le');
I changed the encoding parameter to all of the encoding types listed in the Node documentation, but all of them resulted in this error:
TypeError: Argument at index 2 is invalid: Invalid encoding
All I want to be able to do is be able to read the data from "datalog.txt." Any help would be greatly appreciated!
NOTE: Once I can read the data of the file, I want to be able to get a list of all the lines of the file.
Encoding and type are an object:
const data = fs.readFileSync('datalog.txt', {encoding:'utf16le'});
Okay, after a few hours of troubleshooting a looking at the docs I figured out a way to do this.
try {
// get metadata on the file (we need the file size)
let fileData = fs.statSync("datalog.txt");
// create ArrayBuffer to hold the file contents
let dataBuffer = new ArrayBuffer(fileData["size"]);
// read the contents of the file into the ArrayBuffer
fs.readSync(fs.openSync("datalog.txt", 'r'), dataBuffer, 0, fileData["size"], 0);
// convert the ArrayBuffer into a string
let data = String.fromCharCode.apply(null, new Uint16Array(dataBuffer));
// split the contents into lines
let dataLines = data.split(/\r?\n/);
// print out each line
dataLines.forEach((line) => {
console.log(line);
});
} catch (err) {
console.error(err);
}
Hope it helps someone else with the same problem!
This works for me:
index.js
const fs = require('fs');
// Write
fs.writeFileSync('./customfile.txt', 'Content_For_Writing');
// Read
const file_content = fs.readFileSync('./customfile.txt', {encoding:'utf8'}).toString();
console.log(file_content);
node index.js
Output:
Content_For_Writing
Process finished with exit code 0

find words that start with specific letter

I'm trying to read file.txt with some content like this:
jone
sia
alex
jad
and using node js I want to find the words that start with letter j
this is what I write:
let fs = require('fs');
fs.readFile('./file.txt', (err, info)=>{
let j;
let con = 0;
console.log(err)
if(err) return;
for (j=0; j < info.length; ++j)
if (info[j] == 10)
con++;
console.log(con)
if(info.indexOf('j') > -1){
console.log(info.toString())
}
})
I want to print the number of lines in text file and the words that start with letter j
but the counter result is 3 while it should be 4 and it prints all info:
jone
sia
alex
jad
while it should print jone and jad only
how solve this
You can use the readline build in core module and do something like this:
var rl = require('readline'), fs = require('fs')
var lineReader = rl.createInterface({ input: fs.createReadStream('file.txt') })
lineReader.on('line', function (name) {
if(name.startsWith('j'))
console.log(name)
})
See it working here
Here is your file.txt:
jone
sia
alex
jad
And here is the code:
const fs = require('fs');
const output = fs
.readFileSync('file.txt', 'utf8')
.trim()
.split('\n')
.filter(word => word.includes('j'));
console.log(output);
This will get you everything that includes 'j'
If you want something that will start with j you can write your own filter function like so:
const fs = require('fs');
const output = fs
.readFileSync('file.txt', 'utf8')
.trim()
.split('\n');
function filter(names, index, letter) {
return names.filter(word => word.charAt(index) === letter);
}
console.log('Length of originanl list: ', output.length);
console.log('Filtered List: ', filter(output, 0, 'j'));
console.log('Length of filtered list: ', filter(output, 0, 'j').length);
Live Demo Here
I suggest using the regular expressions approach.
info should be of type string, therefore it is possible for you to use the String.prototype function match(), like so:
let matches = info.match(expression);
or in your case: let matches = info.match(/\bj\w+/g); (example)
you can use regex to detect how many lines the text files has by detecting how many line breaks you have in your raw data (if possible):
let lines = info.match(/\n/g).length + 1; (example)
All these answers are incredibly over-complicated.
Simply iterate through all words and check if it start with the letter:
for (const word of wordList.split("\n")) {
if (word.startsWith("j")) console.log(`${word} start with the letter j`);
}

Need to write an array of objects to a file from nodejs

I have an array of objects like below that i have to write to a file with node js, the aim is to write one item per line into one file :
cont obj = [{a:1},{b:2}]
Output file content expected :
//file.json
{a:1}
{b:2}
My code without success
jsonfile.writeFileSync(filePath, JSON.stringify(obj), 'utf-8');
/*
* [\{a:1\},\{b:2\}] <=== a string in one line with special characters
* doesn't fit on my need
*/
If someone could helps me,
Thank you.
You could simply:
const text = arr.map(JSON.stringify).reduce((prev, next) => `${prev}\n${next}`);
fs.writeFileSync(filePath, text, 'utf-8');
(That's a slight modification of #ronapelbaum approach)
You can use util.inspect and loop.
const arr = [{a:1}, {b:2}];
const filePath = "path/to/json";
for (let obj of arr)
fs.appendFileSync (filePath, util.inspect (obj) + "\n")
Or, if you'd like to accumulate the data to save on write operations:
const arr = [{a:1}, {b:2}];
const data = arr.reduce ((a, b) => a + util.inspect (b) + "\n", "");
const filePath = "path/to/json";
fs.writeFileSync (filePath, data);
The final file will fit your requirements:
{ a: 1 }
{ b: 2 }
when you're using the jsonfile library, you don't need to use JSON.stringify(obj).
in your case, you don't really want to write a valid json...
consider this:
const text = arr.reduce((txt, cur) => txt + '\n' + JSON.stringify(cur), '');
fs.writeFileSync(filePath, text, 'utf-8');

Write a line into a .txt file with Node.js

I want to use Node.js to create a simple logging system which prints a line before the past line into a .txt file. However, I don't know how the file system functionality from Node.js works.
Can someone explain it?
Inserting data into the middle of a text file is not a simple task. If possible, you should append it to the end of your file.
The easiest way to append data some text file is to use build-in fs.appendFile(filename, data[, options], callback) function from fs module:
var fs = require('fs')
fs.appendFile('log.txt', 'new data', function (err) {
if (err) {
// append failed
} else {
// done
}
})
But if you want to write data to log file several times, then it'll be best to use fs.createWriteStream(path[, options]) function instead:
var fs = require('fs')
var logger = fs.createWriteStream('log.txt', {
flags: 'a' // 'a' means appending (old data will be preserved)
})
logger.write('some data') // append string to your file
logger.write('more data') // again
logger.write('and more') // again
Node will keep appending new data to your file every time you'll call .write, until your application will be closed, or until you'll manually close the stream calling .end:
logger.end() // close string
Note that logger.write in the above example does not write to a new line. To write data to a new line:
var writeLine = (line) => logger.write(`\n${line}`);
writeLine('Data written to a new line');
Simply use fs module and something like this:
fs.appendFile('server.log', 'string to append', function (err) {
if (err) return console.log(err);
console.log('Appended!');
});
Step 1
If you have a small file
Read all the file data in to memory
Step 2
Convert file data string into Array
Step 3
Search the array to find a location where you want to insert the text
Step 4
Once you have the location insert your text
yourArray.splice(index,0,"new added test");
Step 5
convert your array to string
yourArray.join("");
Step 6
write your file like so
fs.createWriteStream(yourArray);
This is not advised if your file is too big
I created a log file which prints data into text file using "Winston" logger. The source code is here below,
const { createLogger, format, transports } = require('winston');
var fs = require('fs')
var logger = fs.createWriteStream('Data Log.txt', {
flags: 'a'
})
const os = require('os');
var sleep = require('system-sleep');
var endOfLine = require('os').EOL;
var t = ' ';
var s = ' ';
var q = ' ';
var array1=[];
var array2=[];
var array3=[];
var array4=[];
array1[0] = 78;
array1[1] = 56;
array1[2] = 24;
array1[3] = 34;
for (var n=0;n<4;n++)
{
array2[n]=array1[n].toString();
}
for (var k=0;k<4;k++)
{
array3[k]=Buffer.from(' ');
}
for (var a=0;a<4;a++)
{
array4[a]=Buffer.from(array2[a]);
}
for (m=0;m<4;m++)
{
array4[m].copy(array3[m],0);
}
logger.write('Date'+q);
logger.write('Time'+(q+' '))
logger.write('Data 01'+t);
logger.write('Data 02'+t);
logger.write('Data 03'+t);
logger.write('Data 04'+t)
logger.write(endOfLine);
logger.write(endOfLine);
function mydata() //user defined function
{
logger.write(datechar+s);
logger.write(timechar+s);
for ( n = 0; n < 4; n++)
{
logger.write(array3[n]);
}
logger.write(endOfLine);
}
var now = new Date();
var dateFormat = require('dateformat');
var date = dateFormat(now,"isoDate");
var time = dateFormat(now, "h:MM:ss TT ");
var datechar = date.toString();
var timechar = time.toString();
mydata();
sleep(5*1000);

Resources