קורס Node.JS שיעור תרגול קבצים ותיקיות


זה נושא דיון מלווה לערך המקורי ב- https://www.tocode.co.il/bundles/nodejs/lessons/12-lab-files-and-directories

תרגיל 1 החלק הראשון
האם זאת הכוונה ? ממש לבדוק אם הניסיון קריאה לא מחזיר שגיאה ?

const express = require('express');
const fs = require('fs');

const app = express();


app.get('/',(req,res)=>{
   
   fs.readdir('.' , (err , files)=>{
       for(let val of files){
           fs.readFile('./'+val ,'utf-8',(err,content)=>{
               if(err){
                   console.log(val + ' - library');
               }else{
                   console.log(val + ' - file');
               }
           });
       }
   });

});

app.listen(3000);

***המלצה - לתת את הפתרונות של התרגול למי שנתקע שיבין מהפתרון את הטעות שלו…

אני מנסה לכתוב לקובץ את התוצאה אבל אני כל הזמן מקבל שגיאות.
אשמח לעזרתך אם הסבר קצר איפה אני טועה
תודה

const express = require('express');
const fs = require('fs');

const app = express();
const out = fs.createWriteStream('practice.txt');



app.get('/',(req,res)=>{


out.on('error',(err)=>{
    console.log(err);
});



    fs.readdir('.' , (err , files)=>{
        for(let val of files){
            fs.readFile('./'+val ,'utf-8',(err,content)=>{
                if(err){
                    fs.readdir('./'+val,'utf-8',(err,files)=>{
                        for(let val of files){
                            console.log(val + 'file of library');
                            out.write(val + 'file of library');
                           
                        }   
                    });
                    console.log(val + ' - library');
                }else{
                    console.log(val + ' - file');
                }
            });
        }
    });
    out.end();
});

app.listen(3000);

הי,

(לגבי ההמלצה- אני מקווה שלא יפתיע אותך לשמוע שאתה לומד יותר טוב אם אתה שובר את הראש יומיים ואז פותר בסוף מאשר אם אתה שובר את הראש חצי שעה ואז מסתכל בפיתרון. אני בכוונה משאיר את התרגילים פתוחים. וכן מבין את התסכול. והאמת אפילו מחפש אותו. תסכול זה חלק חשוב מתהליך הלמידה…).

עד לפה חפירות עכשיו לנוד

רוצה להדביק כאן את הודעת השגיאה?

אנחנו מסתכלים על החלק השלישי של התרגיל הראשון נכון? משהו פה לא מסתדר לי עם האינדנטציה. כל הקוד הזה נמצא בתוך app.get הראשי? רוצה לתאר במילים שלך מה ניסית לעשות שם?

const express = require('express');
const app = express();
const testFolder = './code node/';
const fs = require('fs');
const path = require('path');
const fsExtra = require('fs-extra')

fs.readdir(__dirname, function (err, files) {
    if (err) throw err;
    files.forEach(file => {
        fs.stat(file, function (err, stat) {
            if (err) {
                console.log(`unknow stat:${file}`);
                return;
            }
            if (stat.isFile()) {
                console.log(`it's file ${file}`);
            } else if (stat.isDirectory()) {
                console.log(`${file} a derctory  `);
                fs.readFile(file, 'utf8', function (err, data) {
                    if (err) {
                        logger.error('samething not good');
                        return;
                    }
                    console.log(data);
                })
            } else {
                console.log('something else');
            }
        })
    });


})

משום מה הקוד לא עובד לי אשמח לעזרה …

הקוד ברובו עובד חוץ מהחלק של readfile

הי @Hadar_Leiner
מה בדיוק לא עובד? מה השגיאה שאת מקבלת?

אין שגיאה זה פשוט לא קורא או קורה החלק הזה בקוד

כשניסיתי עכשיו להריץ על המחשב שלי קיבלתי את ההודעה ‘samething not good’ מספר פעמים. יכול להיות שאת לא רואה אותה כי במקום console.log השתמשת ב logger.error ? רוצה לנסות להחליף אותה ל console.log ותראי אם ההודעה מופיעה?

תודה הסתדר לי כנראה לא שמתי לב לזה…

בשלב השלישי עדכנו את הסקריפט כך שיוכל גם למחוק את כל הקבצים והתיקיות שיצר: הפעלה של הסקריפט עם הפרמטר create תיצור את כל הקבצים והתיקיות, והפעלה עם הפרמטר destroy תמחק אותם. במילים אחרות ההפעלה הבאה יוצרת את הקבצים והתיקיות:

אפשר הפניה לאיך לפתור את זה?

הי,
יכולה לפרסם פה את הסקריפט שכתבת לחלקים הראשון והשני ואז נראה איך להמשיך משם?

אני רוצה לדעת איך אפשר להגדיר פרמטרים כמו הפרמטר blah פה
node index.js blah

כל הפרמטרים משורת הפקודה נשמרים בתוך מערכת בשם process.argv:
https://nodejs.org/docs/latest/api/process.html#process_process_argv

נסה להדפיס אותו בתחילת התוכנית כדי לראות את התוכן

שלום,

הקוד הוא:

const path = require('path');

const fs = require('fs');

const dirName = path.join(__dirname, './aa')

fs.readdir(dirName, function(err, files) {

    if (err) { console.log(err); }

    files.forEach(e => {

        fs.stat(e, function(err, stat1) {

         if (stat1.isFile())
               console.log(e, 'is file')

            else

                console.log(e, 'not is file')

        })

    })

})

שאלה:יצרתי כמה קבצים בתוך תקיה aa

ואני מריצה את הקוד בdebbuger מה יכולה ליהות הבעיה ,השגיאה היא על הפקודה state1.isFile() ,כאשר אני מריצה בdebbuger , לא נכנס עבור כל קובץ ב-aa לתוך הפונקציית collback של stat (כלומר לשורה המודגשת) אלא רק לאחר שסיים לרוצה על כל הקבצים ואז הוא מגיע לפונקציה callback כאשר ה-stat1 הוא כבר null

נסי להדפיס את ערך המשתנה e בכניסה לפונקציה, בדיוק לפני הקריאה ל stat

מה את חושבת שהוא יהיה? האם הוא יצא כמו שחשבת?

Hi Ynon!
Regarding ex1 - it looks like bash tree function.
I tried to solve it using fs-extra module provides Promises async/await mode.
It seems I need to use async recursion function - it seems challenging.
Can you recommend any lesson about it or external link?
Thanks

That’s my trial to use Promise.all to launch simultaneously the recursive calls over the inner directories.

async function treeRecV2(dirPath='./') {
    let result = {};
    let keys = [];
    let promisesArray = [];

    console.log(dirPath);
    try {
        const dir = await opendir(dirPath);
        for await (const dirEntry of dir) {
            keys.push(dirEntry.name);
            if( dirEntry.isFile()) {
                promisesArray.push(dirEntry.name);
            }
            else {
                // async recursive call
                promisesArray.push(treeRec(`${dirPath}\\${dirEntry.name}`));
            }
        }

        //Here I try to launch simultaneously
        let resultArr = await Promise.all(promisesArray);
        // building "map" obj
        for ( let i = 0; i< keys.length; i++ ) {
            result[keys[i]] = resultArr[i];
        }
        return result;
    } catch (err) {
        console.error(err);
    }
}

async function treeRecWrapper(dirPath)
{
    let start = new Date()
    let hrstart = process.hrtime()
    let result = await treeRecV2(dirPath);
    // let result = await treeRec(dirPath);
    // let result = treeRecSync(dirPath);
    let end = new Date() - start,
        hrend = process.hrtime(hrstart)
    console.info('Execution time: %dms', end)
    console.info('Execution time (hr): %ds %dms', hrend[0], hrend[1] / 1000000)
    console.log(result);
}

const dirPath = 'D:\\YnonPerek\\nodejs\\nodejs-course-demos\\06-exercise';

treeRecWrapper(dirPath).then();

I think it will be easier to start with a non async solution

For the filesystem module, node has sync version for all the functions, for example there is fs.readdirSync and fs.opendirSync, both return the actual value

Start with them and see if you can get a solution; then we’ll change it to async
(however keep in mind that with fs related actions the sync versions are actually much faster and usually preferred)

Ok Thank you, I did it the sync way as well.
It is interesting that sync versions of fs functions work faster.
I am a bit surprised but it is faster even in my mini tests.
I would expect to launch several recursive async calls Promise.all simultaneously, yet it didn;t improve
That’s my sync version

function treeRecSync(dirPath='./') {
    let result = {}
    console.log(dirPath);
    try {
        const dir = opendirSync(dirPath);
        while (true) {
            let dirEntry = dir.readSync();
            if(!dirEntry) {
                break;
            }
            if( dirEntry.isFile()){
                result[dirEntry.name] = dirEntry.name;
            }
            else {
                result[dirEntry.name] = treeRecSync(`${dirPath}\\${dirEntry.name}`);
            }
        }
        return result;
    } catch (err) {
        console.error(err);
    }
}