node js read files line by line - node.js

I am quite new with Node.js.
There is a folder on my computer where I have several textfiles (.fw4 format). I could find all the text files with the node-dir module.
Furthermore I need to get some content of each file from specified columns. Actually this algorithm works fine, using the readline module.
I keep my files name in an array.
Something like this: [ '000037592.fw4', '000037593.fw4', '000037594.fw4' ]
What do I need actually? I would like that this whole system would work synchronously and when I get the first file content (000037592.fw4) it would log something like end of file. And it continues reading the other files from the array.
So far, it has not worked how I wanted.
Thank you so much in advance. I would appreciate any suggestion on how to get a solution for my problem.

Do something like:
var fileArray = [ '000037592.fw4', '000037593.fw4', '000037594.fw4' ];
var i = 0;
readNextFile();
function readNextFile(){
fs.readFile(fileArray[i++], function(result){
handleResult(result);
if(i < fileArray.length){
readNextFile();
}
});
}

Related

What's the most efficient way of extracting information from huge files?

I have to work with really big files (up to 1GB) and I need to extract some relevat information. Currently I parse the file line by line and extract only the information I need, but even so, it takes a lot of time.
I'm using electron because I need cross platform compatibility, what would be a good optimization?
My code looks something like this
const info = [];
readline.on("line", function(line) {
if(condition(line)) {
info.push(line);
}
})

Need Help Understanding Node JS Syntax Error

Can anyone please help me to understand the syntax error based on the attached screenshot below?
My script is supposed to access a given JSON and return the specific value, but somehow it's returning this error.
Edit 1
I tested my script with a dummy JSON and the script didn't return any error, so I suspect my original JSON might be giving problem. Here's my JSON.
{
"og_object": {
"id": "1192199560899293",
"description": "Hi everyone I have an important announcement to make. So ever since Penny started school, I've been having mixed feelings. \u00a0Besides having a bit of space to myself to breathe and rest my brain/legs, I'm actually a bit bittersweet cos my little baby, who used to sleep at weird hours and gobble puree",
"title": "Fighter and Penny's new sibling",
"type": "article",
"updated_time": "2017-04-12T01:17:57+0000"
},
"share": {
"comment_count": 0,
"share_count": 109
},
"id": "http://fourfeetnine.com/2017/03/05/fighter-and-pennys-new-sibling/"
}
Edit 2
Here's my script that I run that produces the error.
var objects = require('./output.txt');
console.log(objects);
output.txt is the file that contains the JSON that I pasted in Edit 1
var objects = require('./output.txt');
The require() function belongs to the module loading system. Despite the name, it can actually load several types of files and directories and not only Node modules. As per the high-level algorithm in pseudocode shown in docs:
require(X)
If X begins with './' or '/' or '../'
a. LOAD_AS_FILE(Y + X)
[...]
LOAD_AS_FILE(X)
If X is a file, load X as JavaScript text. STOP
If X.js is a file, load X.js as JavaScript text. STOP
If X.json is a file, parse X.json to a JavaScript Object. STOP
If X.node is a file, load X.node as binary addon. STOP
Since you get SyntaxError, output.txt does not contain valid JavaScript code.
If you really want to load JSON, you need to enforce subrule #3 by renaming the file to output.json.
Thanks to #Jordan suggestion. The fault is indeed due to wrong file extension. After changing the file extension from .txt to .json, then the syntax error disappeared.

tail -f implementation in node.js

I have created an implementation of tail -f in node.js using socket.io and fs.watch function.
I read the file using fs.readFile, convert it into array of lines and returns it to the client. Stores the current length in variable.
Then whenever the "file changed" event fires, I re-read the whole file, converts it into array of lines. And then compare the old length and current length. and slice it like
fileContent.slice(oldLength, fileContent.length)
this gives me the changed content. So running perfectly fine.
Problem: I am reading the whole file every time the file gets changed, which is not efficient if file is too large. So is there any way, of reading a file once, and then gets the changed content if there is any change?
I have also tried, spawning child process for "tail -f"
var spawn = require ('child_process').spawn;
var child = spawn ('tail', ['-f', logfile]);
child.stdout.on ('data', function (data){
linesArray = data.toString().split("\n")
console.log ( "Data sent" + linesArray[0]);
io.emit('changed', {
data: linesArray,
});
});
the problem with this is:
on("data") event fires multiple time when I save the logfile by writing some content.
On first load, it correctly returns the last ten line of the file. But if there is a change then it return the whole content again and again.
So if you have any idea of solving this problem let me know. Till then I will dig the internet.
So, I got the solution by reading someone else's code. So solution was to use fs.open which will open the file and then instead of reading whole file we can read the particular block from the file using fs.read() function.
To know about the fs.open/fs.read, read this nodejs-file-system.
Official doc : fs.read

learnyounode 'My First I/O' example

This program puzzles me. The goal of this program is to count the number of newlines in a file and output it in command prompt. Learnyounode then runs their own check on the file and sees if their answer matches your answer.
So I start with the answer :
var fs = require('fs');
var filename = process.argv[2];
file = fs.readFileSync(filename);
contents = file.toString();
console.log(contents.split('\n').length - 1);
learnyounode verifies that this program correctly counts the number of new lines. But when I change the program to any of the following, it doesn't print out the same number as learnyounode prints out.
file = fs.readFileSync(C:/Nick/test.txt);
file = fs.readFileSync(test.txt);
Shouldn't nodejs readFileSync be able to input an address and read it correctly?
Lastly, this program is supposed to print out the # of newlines in a program. Why does both the correct program and learnyounode print out the same number that is different from the amount of newlines everytime I run this program?
For example, the number of newlines in test.txt is 3. But running this program prints out a different number everytime, like 45, 15, 2, etc. Yet at the same time, it is verified as a correct program by learnyounode because both their answers match! What is going on?
EDIT:
test.txt looks like this
ok
testing
123
So, I tried your program on my local machine and your program works fine. I am not an expert on learnyounode. I just tried it after your question but I think I understand how it works. As such, here are the answers to your questions:
Shouldn't nodejs readFileSync be able to input an address and read it correctly?
This method from nodejs is working fine. You can try printing the contents of the file and you'll see that there are no problems.
Why does both the correct program and learnyounode print out the same number that is different from the amount of newlines everytime I run this program.
learnyounode is running your program with a different filename as input each time. It verifies the output of your program by running its own copy of correct code against the same file.
But when I change the program to any of the following, it doesn't print out the same number as learnyounode prints out.
That is because at this point, your code is processing a fixed file whereas learnyounode is still processing different files on each iteration.
This tripped me up too. If you read the learnyounode instructions closely they explicitly say...
"The full path to the file to read will be provided as the first command-line argument."
This means they are providing the path to their own file.
When you use process.argv[2], this is passing in the 3rd array item (the learnyounode test txt file) into your script. If you run a console.log(process.argv); you'll see the full array object looks something like this:
[ '/usr/local/bin/node',
'/Users/user/pathstuff/learnyounode/firstio.js',
'/var/folders/41/p2jvc80j26l7nty0sk0zs1z40000gn/T/_learnyounode_1613.txt' ]
The reason the validation numbers begin to mismatch when you substitute your own text file for their is because your file always has 3 lines whereas their unit tests keep passing in different length files via process.argv.
Hope that helps.
when you are using process.argv[2] in learnyounode, the argument is provided by learnyounode automatically, so it prints different number of lines like 45, 15, 2 etc at multiple times verification.
If you remember the second challenge "BABYSTEPS" carefully this was given:
learnyounode will be supplying arguments to your program when you run
learnyounode verify program.js so you don't need to supply them yourself.
That's why different line numbers at program.js verification on multiple times.
there are two different ways.
if you run program like:
node program_name.js
than you need to add path to text file:
node program_name.js text_file.txt
in this case make sure that files are in the same directory.
or you can run it with command:
learnyounode program_name.js
and than default text file will be provided by learnyounode. You can watch content of this text file by using
console.log(buffer)
Problem statement says
The full path to the file to read will be provided as the first
command-line argument.
So you've to pass the path/to/file as an argument.
Remember process.argv
you should use the following method to execute .js files
node program_name.js /path/to/text_file_name
rather than
learnyounode run program_name.js /path/to/text_file_name
on this method, Node.js will run your program with specify files of you enter on the command-line-interface.
wish this answer can help you programming. :)

Relative path to physical path

<rant>
firstly, I've searched a lot and every single question / blog asks/tells about how to convert physical path to relative, never the other way around. If I've missed that question here, I am sorry.
<rant />
So, I have a directory structure very similar to this:
Root
|....Components
|....Classes
|....Utils
|....FileUtils
|....Assets //this is a folder
|....FileAccess.cs
So, in my FileAccess.cs I just want to read the content of a text file and display it on a page.
in my webpage.aspx.cs I am calling the getFileContent() which is in utils.
so the relative path from FileAccess.cs is Assets\spec.txt
So, how on earth can I access that with code?
this is what I am trying / tried:
//function getFileContent() content..
private const string QuestionnairePath = #"Assets\";
return Server.MapPath(QuestionnairePath + "spec.html");
it ALWAYS throws file not found exception and upon debugging it's not selecting the right folder.
I have even tried this:
private const string QuestionnairePath = #"~Utils\FileUtils\Assets\";
that doesn't work either.
This must be very easy. Just can't figure it out, for the life of me. I hate being a newbie sometimes.
Help please,
Thanks.
ps: Ideally, I would just want to use relative path: Assets\ - wonder if that is possible.

Resources