10 Ocak 2018 Çarşamba

Node.js Dersleri 7 - readDir

17 - readDir

http://code-maven.com/list-content-of-directory-with-nodejs
http://stackoverflow.com/questions/38037767/callback-function-in-for-loop-in-callback-function
Here we use the readdir method of the fs class, that gets a path and a callback function as parameters. It will read the content of the directory into memory and when done it will execute the callback with 2 parameters. The first one is the error object in case there was an error. The second one is a callback that will be called when the the operation has finished. If there was an error then the first parameter will hold that information. If everything went well, then the second parameter will be an array with all the items (files, directories, symbolic links, etc.) that were found in the directory.
The listing will contain everything, except of . which point to the current directory and .. which represents the parent directory.
fs modülündeki readdir() method'u, Windows komut satırındaki dir komutu ve Linux komut satırındaki ls komutu gibi çalışır. Bir directory'dekji tüm dosyaları ve klasörleri içeren bir string array return eder.
Şimdi de current directory'deki tüm file'ları/directory'leri tek tek ele alıp bunların size'larını yazdıran bir örnek görelim:
ÇOK ÖNEMLİ BU ÖRNEĞİ ANLA!
Question :
Why doesn't the below code works properly? The author says it causes from the first parameter of fs.stat() method. The correct way of doing this is shown in the last two working examples. I don't understand the difference between the working and non-working examples and why the first example does not work properly and the last two examples works properly.
var fs = require('fs');
if (process.argv.length <= 2) {
   console.log("Usage: " + __filename + " path/to/directory");
   process.exit(-1);
}
var path = process.argv[2];
fs.readdir(path, function(err, items) {
   for (var i=0; i<items.length; i++) {
       var file = path + '/' + items[i];
       console.log("Start: " + file);
       fs.stat(file, function(err, stats) {
           console.log(file);
           console.log(stats["size"]);
       });
   }
});
The output is :
$ node examples/node/list_dir_direct.js ~/work/code-maven.com/examples/
Start: /home/gabor/work/code-maven.com/examples//blocking-read-file.js
Start: /home/gabor/work/code-maven.com/examples//node_hello_world.js
Start: /home/gabor/work/code-maven.com/examples//node_hello_world_port.js
Start: /home/gabor/work/code-maven.com/examples//non-blocking-read-file.js
Start: /home/gabor/work/code-maven.com/examples//process_exit.js
Start: /home/gabor/work/code-maven.com/examples//raw_command_line_arguments.js
Start: /home/gabor/work/code-maven.com/examples//read_dir.js
Start: /home/gabor/work/code-maven.com/examples//stats.js
/home/gabor/work/code-maven.com/examples//stats.js
97
/home/gabor/work/code-maven.com/examples//stats.js
243
/home/gabor/work/code-maven.com/examples//stats.js
270
/home/gabor/work/code-maven.com/examples//stats.js
151
/home/gabor/work/code-maven.com/examples//stats.js
18
/home/gabor/work/code-maven.com/examples//stats.js
324
/home/gabor/work/code-maven.com/examples//stats.js
27
/home/gabor/work/code-maven.com/examples//stats.js
1382
The debugging printout printed the names as expected, but then inside the callback of fs.stat() we keep printing out the same filename. comparing the results to the output of
$ ls -l ~/work/code-maven.com/examples/
total 64
-rw-r--r--  1 gabor  staff    97 Jan 29 14:26 blocking-read-file.js
-rw-r--r--  1 gabor  staff   243 Jan 27 12:34 node_hello_world.js
-rw-r--r--  1 gabor  staff   270 Jan 27 12:34 node_hello_world_port.js
-rw-r--r--  1 gabor  staff   151 Jan 29 14:26 non-blocking-read-file.js
-rw-r--r--  1 gabor  staff    18 Jan 31 08:24 process_exit.js
-rw-r--r--  1 gabor  staff    27 Jan 29 14:54 raw_command_line_arguments.js
-rw-r--r--  1 gabor  staff   324 Jan 31 15:26 read_dir.js
-rw-r--r--  1 gabor  staff  1382 Jan 31 10:45 stats.js
The sizes seem to match the filenames, because these were printed in the same order as we called fs.stat(), but for some reason the content of the file variable was the same for every callback. This happens because the file variable is just a simple global variable (from the point of view of the callback) and by the time the first callback was executed, the file variable was already assigned the last entry in the directory.
The below code works correctly.
var fs = require('fs');
if (process.argv.length <= 2) {
   console.log("Usage: " + __filename + " path/to/directory");
   process.exit(-1);
}
var path = process.argv[2];
fs.readdir(path, function(err, items) {
   for (var i=0; i<items.length; i++) {
       var file = path + '/' + items[i];
       console.log("Start: " + file);
       fs.stat(file, generate_callback(file));
   }
});
function generate_callback(file) {
   return function(err, stats) {
           console.log(file);
           console.log(stats["size"]);
       }
};
Also, the below code works correctly, too.
var fs = require('fs');
if (process.argv.length <= 2) {
   console.log("Usage: " + __filename + " path/to/directory");
   process.exit(-1);
}
var path = process.argv[2];
fs.readdir(path, function(err, items) {
   for (var i=0; i<items.length; i++) {
       var file = path + '/' + items[i];
       console.log("Start: " + file);
       fs.stat(file, function(f) {
           return function(err, stats) {
              console.log(f);
              console.log(stats["size"]);
           }
       }(file));
   }
});
Answer :
In the first example, pass-by-reference works. File variable is passed by reference thus callback function takes the last value of file variable and works incorrectly. In the second and third examples, pass-by-value works. File variable is passed by value thus callback function takes each file's name correctly. (1. örnekte callback fonksiyonunda kullanılan file isimli variable'ın değeri, for loop'un sonunda elde edilen son değerdir. 2. ve 3. örnekte ise, herbir file'ın ismi file variable'a assign edilir. File variable pass-by-reference ile fonksiyona pass edilir. Yani fonksiyonun içerisinde file'ın değeri değişmez. 1. örnekte ise, callback fonksiyonunda kullanılacak file variable'ının değeri her döngüde değişecektir, callback fonksiyonları çalışmaya başladığında file variable'ın değeri hep aynıdır, for döngüsünün son çalışmasında elde edilen değerdir, yani baktığımız path'deki son dosya ismidir. Dolayısıyla tüm for döngüsünde son dosyanın ismi yazılır, herbir dosyanın ismi değil.)
To search more on this topic :
- https://docs.nodejitsu.com/articles/file-system/how-to-search-files-and-directories-in-nodejs/
- http://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search  findit module
- https://www.npmjs.com/package/findit findit module
- This is a particularly good use case for using items.forEach() instead of a plain for loop.
items array'inin forEach() loop'u içerisinde kullansaydık bu örneği daha iyi olurdu. Bunu araştır.

18 - difference btw __dirname and process.cwd()

http://www.hacksparrow.com/understanding-directory-references-in-node-js.html
http://stackoverflow.com/questions/9874382/whats-the-difference-between-process-cwd-vs-dirname
process.cwd() returns the current working directory, i.e. the directory from which you invoked the node command. (current working directory'dir, komut satırınca hangi directory'de komut vererek çalıştırdıysak node programımızı bu directory'yi return eder.)
process.cwd() is synonym to . for all cases except for require() ? require works relative to current executing file. For more info , visit http://stackoverflow.com/questions/16727045/node-js-express-js-relative-paths-dot-or-dirname-or-without-any-prefix
__dirname returns the directory name of the directory containing the JavaScript source code file. (çalışan .js dosyasının bulunduğu directory return edilir. fs.existsSync -> çalıştığımız directory ve .js dosyasının bulunduğu directory aynı ise true return eder. Deprecated'dır. Bunun yerine fs.stat() kullanmalıyız. )
Example:
Create a directory named base with the following tree under it: (Base isimli bir directory yaratalım, bu directory'nin altında şöyle bir hiyerarşi olsun)
.
── app.js
└── /one
   ── one.js
   └── /two
       └── two.js
The content for app.js
var fs = require('fs');
console.log('------ base-app ------');
console.log('./app.js: ', fs.existsSync('./app.js')); //    true
console.log('__dirname: ', __dirname); // app.js dosyasının yeri
console.log('process.cwd(): ', process.cwd()); // komutun verildiği yer

require('./one/one.js');
Output :
In the directory base:
$ node app.js

------ base-app ------
./app.js:  true
__dirname:  /Projects/base
process.cwd():  /Projects/base
------ mod-one ------
./one.js:  false
__dirname:  /Projects/base/one
process.cwd():  /Projects/base
------ mod-two ------
./two.js:  false
__dirname:  /Projects/base/one/two
process.cwd():  /Projects/base
The content for one.js
var fs = require('fs');
console.log('------ mod-one ------');
console.log('./one.js: ', fs.existsSync('./one.js'));
console.log('__dirname: ', __dirname); // one.js dosyasının yeri
console.log('process.cwd(): ', process.cwd()); // komutun verildiği yer

require('./two/two.js');
In the directory one:
$ node one.js

------ mod-one ------
./one.js:  true
__dirname:  /Projects/base/one
process.cwd():  /Projects/base/one
------ mod-two ------
./two.js:  false
__dirname:  /Projects/base/one/two
process.cwd():  /Projects/base/one
The content for two.js
var fs = require('fs');
console.log('------ mod-two ------');
console.log('./two.js: ', fs.existsSync('./two.js'));
console.log('__dirname: ', __dirname); // two.js dosyasının yeri
console.log('process.cwd(): ', process.cwd());   // komutun verildiği yer
In the directory two:
$ node two.js

------ mod-two ------
./two.js:  true
__dirname:  /Projects/base/one/two
process.cwd():  /Projects/base/one/two
Now, run one.js from the directory two:
$ node ../one.js

------ mod-one ------
./one.js:  false
__dirname:  /Projects/base/one
process.cwd():  /Projects/base/one/two
------ mod-two ------
./two.js:  true
__dirname:  /Projects/base/one/two
process.cwd():  /Projects/base/one/two
Did you notice anything noteworthy?
./ and process.cwd() refers to the directory on which the node command was called. It does not refer to the directory of the file being executed.
__dirname refers to the directory where the file being executed resides.

So be careful, the next time you use ./process.cwd(), or __dirname.

19 - fs.stat()

http://code-maven.com/system-information-about-a-file-or-directory-in-nodejs
fs modülündeki stat method'unu 2 farklı şekilde kullanabiliriz.
- using the synchronous version, which doesn't use a callback. It simply returns the result instead. Example:
var fs = require('fs');
var stats = fs.statSync(pathname);
console.log(stats.isDirectory());
- using the asynchronous version, which uses a callback. Example:
fs.stat(path, callback);
Explanation:
fs.stat() method'unun asenkron versiyonunu inceleyeceğiz aşağıdaki örnekte.
examples/node/stats.js
var fs = require('fs'); 
if (process.argv.length <= 2) {
   console.log("Usage: " + __filename + " path/to");
   process.exit(-1);
}
var path = process.argv[2]; 
fs.stat(path, function(err, stats) {
   console.log(path); // ekrana examples yazdırılır.
   console.log(); // prints new line
   console.log(stats);   // stats object'i ekrana yazdıralım.
   console.log(); // prints new line
   if (stats.isFile()) { // examples bir dosya mı ?
       console.log('file');
   }
   if (stats.isDirectory()) { // examples bir directory mi ? Evet
       console.log('directory'); // Ekrana directory yazdırılır.
   }
   console.log('    size: ' + stats["size"]); // stats object'inin sahip olduğu size variable'ının değerine erişip ekrana yazdıralım. Böylece example directory'sinin size'ını öğreniriz.
   console.log('    mode: ' + stats["mode"]);
   console.log('    others eXecute: ' + (stats["mode"] & 1 ? 'x' : '-'));
   console.log('    others Write:   ' + (stats["mode"] & 2 ? 'w' : '-'));
   console.log('    others Read:    ' + (stats["mode"] & 4 ? 'r' : '-'));
   console.log('    group eXecute:  ' + (stats["mode"] & 10 ? 'x' : '-'));
   console.log('    group Write:    ' + (stats["mode"] & 20 ? 'w' : '-'));
   console.log('    group Read:     ' + (stats["mode"] & 40 ? 'r' : '-'));
   console.log('    owner eXecute:  ' + (stats["mode"] & 100 ? 'x' : '-'));
   console.log('    owner Write:    ' + (stats["mode"] & 200 ? 'w' : '-'));
   console.log('    owner Read:     ' + (stats["mode"] & 400 ? 'r' : '-')); 
   console.log('    file:           ' + (stats["mode"] & 0100000 ? 'f' : '-'));
   console.log('    directory:      ' + (stats["mode"] & 0040000 ? 'd' : '-'));
});
fs.stat(path, function(err, stats) {
The callback function will receive an error object - if there was an error-, and a fs.Stats object. (Bu örnekteki, callback fonksiyonu 2 tane argument alır:
- err : Error object'dir. fs.stat() method'u gerçekleşirken hata olursa error object set edilir.
- stat : fs.Stats object'dir, yani fs modülündeki Stats class'ından yaratılmış bir object'dir. )
Komut satırından şu komutu vererek bu modülü çalıştıralım:
 node examples/node/stats.js examples
Output:
examples
{ dev: 16777220,
 mode: 16877,
 nlink: 11,
 uid: 501,
 gid: 20,
 rdev: 0,
 blksize: 4096,
 ino: 32548075,
 size: 374,
 blocks: 0,
 atime: Sat Jan 31 2015 10:56:30 GMT+0200 (IST),
 mtime: Sat Jan 31 2015 10:52:13 GMT+0200 (IST),
 ctime: Sat Jan 31 2015 10:52:13 GMT+0200 (IST) }
   directory
   size: 374
   mode: 16877
   others eXecute: x
   others Write:   -
   others Read:    r
   group eXecute:  x
   group Write:    w
   group Read:     r
   owner eXecute:  x
   owner Write:    w
   owner Read:     r
   file:           -
   directory:      d
We can compare that with the output of the appropriate Unix ls command:
$ ls -ld examples
drwxr-xr-x  11 gabor  staff  374 Jan 31 10:52 examples
The Stats object contains some data retrieved from the inode table (in our case it looked like this:) ( Bu örnekte, Stats object'ini console'a yazdırdık, console'daki çıktı aşağıdaki gibidir. Stats object'inin içeriği, inode table'dan elde edilir, OS dersinden hatırla. )
{ dev: 16777220,
 mode: 16877,
 nlink: 11,
 uid: 501,
 gid: 20,
 rdev: 0,
 blksize: 4096,
 ino: 32548075,
 size: 374,
 blocks: 0,
 atime: Sat Jan 31 2015 10:56:30 GMT+0200 (IST),
 mtime: Sat Jan 31 2015 10:52:13 GMT+0200 (IST),
 ctime: Sat Jan 31 2015 10:52:13 GMT+0200 (IST) }
and it provides a few methods for more convenience.
dev is the device number. It might be interesting if you have multiple disks or partitions mounted.
mode contains a lot of information, including the type of the thing (file/directory/symbolic link) and the permissions on that thing.
uid is the user-id of the owner of this thing.
gid is the group-id of the owner of this thing.
size is, the size of the thing in bytes.
atimemtime, and ctime are 3 different timestamps representing the last access time, the last modify time and the create time of the thing.
isFile() will return True if the thing is a file.
isDirectory() will return True it the thing is a directory.

Mode and file access rights
We need to use special bitwise masks on that number to check if specific bits are on or off in that number. For example,
mode & 1 will be 1 if the right-most bit in mode was on. Otherwise this will be 0.
mode & 2 will be 2 if he second bit from the right was on, and 0 if it was not.
mode & 4 will be 4 if the third bit from the right was on, and 0 if it was not.
Luckily numbers, except of 0, are considered True in JavaScript. So we could use the ternary operator ?: to returns some interesting character if the expression is different from 0 and return - if the expression was 0.
Besides the read-write-execute flags, we can also extract the file-type from the the mode value, but for those we have already seen a set of more readable convenience methods.
( fs.stats object'in içerdiği mod variable'ının değeri bize read/write'lar, isDirectory(), isFile() vs. gibi şeyleri öğrenmemizi sağlar. Örneğin, mod 1010111010110 gibi bir değer ise bu değerin sondan 2.değeri olan 1, bu dosyaya other'ların write yetkisine sahip olduğunu gösterir.  Bu değeri 000000000010 ile and ilişkisine sokarsak 1 haricindeki tüm bitler 0 olduğu için sonuçtaki bu bitler de sıfır olacaktır. Sondan ikinci bit her ikisinde de 1 olduğu için sonuçtaki bu bit de 1 olacaktır.  )
For more on File System object, read the tutorial :
http://www.tutorialspoint.com/nodejs/nodejs_file_system.htm

20 - timeouts in node

https://nodejs.org/docs/latest/api/timers.html
http://peterlyons.com/problog/2014/03/settimeout-and-friends setimmediate'a burdan bak.
http://stackoverflow.com/questions/15349733/setimmediate-vs-nexttick  setimmediate anlamadım.
Explanation 1 :
http://www.java2s.com/Tutorials/Javascript/Node.js_Tutorial/0270__Node.js_setTimeout_setInterval.htm
Timeout fonksiyonları global fonksiyonlardır. Bunları kullanabilmek için herhangi bir şey require etmemize gerek yoktur.
setTimeout
setTimeout sets up a function to be called after a specified delay in milliseconds.(Belirli süre sonunda belirli bir fonksiyonun çağırılmasını istiyorsak setTimeout fonksiyonunu kullanmalıyız. )
Aşağıdaki örnekte, 1000 milisaniye sonra sadece 1 defalığına çağırılmasını istediğimiz anonymous fonksiyonu setTimeout fonksiyonuna 1.argument olarak veriyoruz.
setTimeout(function () {
   console.log('timeout completed');
}, 1000);

setInterval
Similar to the setTimeout function. setTimeout only executes the callback function once after the specified duration. setInterval calls the callback repeatedly after every passing of the specified duration. (setTimeout() fonksiyonuna benzer, setTimeout() fonksiyonununa verdiğimiz callback fonksiyonu belirli süre sonunda sadece 1 defa çalışır. setInterval() fonksiyonu ise belirli zaman aralıklarında sürekli bir şekilde çalışır.)
The following code prints out second passed after every second. (Aşağıdaki kodda setInterval fonksiyonuna verdiğimiz ilk parametredeki callback fonksiyonu her saniyede bir çalışacaktır.)
setInterval(function () {
   console.log('second passed');
}, 1000);
clearTimeout/clearInterval
Both setTimeout and setInterval return an object that can be used to clear the timeout/interval using the clearTimeout/clearInterval functions.
The following code demonstrates how to use clearInterval to call a function after every second for five seconds, and then clear the interval after which the application will exit.
( setTimeout() ve setInterval() fonksiyonları, bir object return eder. Bu object'i bir variable'a assign ederiz, sonra bu variable'ı clearTimeout ve clearInterval() fonksiyonlarına vererek timeout ve interval'i clear edebiliriz(deactive edebiliriz, silebiliriz). Aşağıdaki örnekte, 5 saniyede bir çalışacak bir fonksiyon ayarlıyoruz setInterval() fonksiyonunu kullanarak. Sonra clearInterval() fonksiyonunu çağırarak bunu iptal ederiz. )
var count = 0;
var intervalObject = setInterval(function () {
       count++;
       console.log(count, 'seconds passed');
       if (count == 5) {
           console.log('exiting');
           clearInterval(intervalObject);
       }
   }, 1000);
Explanation 2 :
http://www.informit.com/articles/article.aspx?p=2265407&seqNum=4
Two strings are passed in and then written to the console after a second of waiting before executing the method. You might need to cancel the timeout before the execution of the callback function. ThesetTimeout() method returns an identifier that can be used with the clearTimeOut() method.
A simple example of using the clearTimeout() method appears below:
var timeOut = setTimeout(function(str1, str2) {
 console.log(str1 + " " + str2);
}, 1000, "Hello.", "How are you?");
clearTimeout(timeOut);
The example above cancels the function call immediately (in real-world scenarios the cancellation would occur based on an event).
a

21 - packages and node_modules

mkdir deneme
cd deneme
npm init -> package.json yaratır.
npm install underscore --save -> current directory'deki node_modules folder'ının içine underscore ve bu package'ın dependency'lerini kopyalar. package.json'ı günceller.
http://www.java2s.com/Tutorials/Javascript/Node.js_Tutorial/1220__Node.js_NPM.htm
http://www.java2s.com/Tutorials/Javascript/Node.js_Tutorial/1200__Node.js_Packages.htm

22 - How to store local configuration data & console.dir and console.log

https://docs.nodejitsu.com/articles/file-system/how-to-store-local-config-data/
http://stackoverflow.com/questions/11954152/whats-the-
difference-between-console-dir-and-console-log

23 - Node.js File System object

http://www.tutorialspoint.com/nodejs/nodejs_file_system.htm
fs.watchFile()

Hiç yorum yok:

Yorum Gönder