نحوه خواندن و نوشتن فایل ها با Node.js
Node.js یک محیط اجرای قدرتمند جاوا اسکریپت است که به شما امکان می دهد کد JS را خارج از مرورگر اجرا کنید. و بخش اساسی بسیاری از برنامههای Node.js شامل خواندن و نوشتن فایلها میشود – خواه متن، JSON، HTML یا سایر فرمتهای فایل. پس باید نحوه خواندن و نوشتن فایل ها را بدانید.
فایل ها ستون فقرات ذخیره سازی داده ها هستند. Node.js یک ماژول قدرتمند 'fs' (سیستم فایل) برای تعامل یکپارچه با این فایل ها ارائه می دهد. فرض کنید می خواهم یک فایل JSON را در Node.js بخوانم. ماژول fs می تواند در این مورد به من کمک کند.
در این آموزش، عملکردهای اصلی این ماژول را توضیح میدهم، تکنیکهای مختلف برای خواندن انواع فایلهای مختلف را تحلیل میکنم، و برخی از بهترین روشها را کشف میکنم تا عملیات مدیریت فایل شما را روانتر و کارآمدتر کند.
در طول این آموزش، ما همه چیز را از وارد کردن بسته تا استفاده از آن برای کار با فایل ها به صورت ناهمزمان پوشش خواهیم داد. بیایید این سفر یادگیری عملیات فایل با Node.js را شروع کنیم!
فهرست مطالب
نحوه خواندن و نوشتن فایل ها با Node.js
راه های خواندن فایل ها در Node.js
Node.js fs
Module
ماژول Node.js File System (fs) جزء ضروری محیط زمان اجرا Node.js است. این ویژگی های مختلفی را برای تعامل با سیستم فایل رایانه شما فراهم می کند.
ماژول fs به شما امکان خواندن، نوشتن، به روز رسانی، حذف و مدیریت فایل ها و دایرکتوری ها را می دهد. این ماژول به ویژه برای مدیریت عملیات مربوط به فایل در هر دو حالت همزمان و ناهمزمان مفید است.
بیایید جنبه های کلیدی ماژول را تجزیه کنیم:
ماژول fs در هسته خود مجموعه ای از API ها را برای تعامل با سیستم فایل ارائه می کند. راه هایی برای انجام فعالیت های اساسی مانند خواندن محتویات فایل، نوشتن داده ها در فایل ها، ایجاد دایرکتوری ها، حذف فایل ها و غیره ارائه می کند.
این ماژول شامل روش های همزمان و ناهمزمان برای تعامل با فایل ها است. روش های همزمان اجرای برنامه را تا زمانی که عملیات کامل شود مسدود می کند. اما روشهای ناهمزمان برای سناریوهایی ایدهآل هستند که نیاز به انجام کارهای همزمان بدون توقف اجرای کل برنامه داریم.
این ماژول همچنین از مدیریت دایرکتوری ها مانند ایجاد دایرکتوری ها، حذف دایرکتوری ها و فهرست کردن محتویات دایرکتوری پشتیبانی می کند.
این ماژول همچنین از کار با جریانهای فایل پشتیبانی میکند و امکان مدیریت کارآمد فایلهای بزرگ را با خواندن یا نوشتن دادهها در تکهها بدون بارگیری کل محتوا در حافظه فراهم میکند. همچنین استفاده از بافرها را برای مدیریت داده های باینری تسهیل می کند که به فعالیت هایی مانند تبدیل و دستکاری داده ها کمک می کند.
پیش نیازها
برای ادامه آموزش، توصیه می کنم پیش نیازهای زیر را داشته باشید:
درک اولیه جاوا اسکریپت : آشنایی با جاوا اسکریپت ضروری است، زیرا Node.js از جاوا اسکریپت استفاده می کند.
Node.js نصب شده : مطمئن شوید که Node.js روی سیستم شما نصب شده است. می توانید Node.js را از وب سایت رسمی آن دانلود و نصب کنید.
ویرایشگر متن/IDE : یک ویرایشگر متن یا یک محیط توسعه یکپارچه (IDE) را نصب کرده و آماده استفاده کنید.
نحوه خواندن و نوشتن فایل ها با Node.js
بیایید به یک مثال برای درک فرآیند خواندن و نوشتن فایل ها در Node.js نگاه کنیم. ما سناریویی را فرض می کنیم که در آن دو فایل داریم - name.json و address.json.
محتوای داخل name.json به شکل زیر است:
[ { "id" : 1 , "name" : "Alice" }, { "id" : 2 , "name" : "Bob" }, { "id" : 3 , "name" : "Charlie" } ]
محتوای داخل address.json به شکل زیر است:
[ { "id" : 1 , "address" : "123 Main St" }, { "id" : 2 , "address" : "456 Elm St" }, { "id" : 3 , "address" : "789 Oak St" } ]
هدف ما ایجاد یک فایل bio.json است که اطلاعات شناسه، نام و آدرس را ادغام کرده و ساختاری به شرح زیر ایجاد کند:
[ { "id" : 1 , "name" : "Alice" , "address" : "123 Main St" }, { "id" : 2 , "name" : "Bob" , "address" : "456 Elm St" }, { "id" : 3 , "name" : "Charlie" , "address" : "789 Oak St" } ]
بیایید برنامه را بسازیم!
مرحله 1: path
Node.js Packages و fs
را وارد کنید
اجازه دهید با ایجاد یک فایل app.js شروع کنیم. اولین کاری که انجام می دهیم این است که کتابخانه fs را وارد کنیم:
const fs = require ( "fs" );
مرحله 2: خواندن از فایل ها
در مرحله بعد، اجازه دهید داده های دو فایل را با استفاده از Node.js بخوانیم. ما یک تابع کاربردی خواهیم ساخت که به ما کمک می کند این فایل ها را به راحتی در محیط Node.js خود بخوانیم.
async function readJSONFile ( filename ) { try { const data = await fs.readFile(filename, "utf8" ); return JSON .parse(data); } catch (error) { console .error( `Error reading ${filename} : ${error} ` ); return []; } }
از آنجایی که در مثال خود از فایل های JSON استفاده می کنیم، یک متد readJSONFile را در کد خود تعریف کرده ایم. این یک تابع جاوا اسکریپت ناهمزمان است که یک نام فایل را به عنوان ورودی می گیرد و هدف آن برگرداندن محتویات JSON تجزیه شده آن فایل است.
در داخل یک بلوک try، ما سعی می کنیم فایل را با استفاده از fs.readFile در Node با نام فایل مشخص شده و رمزگذاری "utf8" بخوانیم. در صورت موفقیت آمیز بودن، تابع محتوای فایل را به صورت JSON با استفاده از JSON.parse تجزیه می کند و آن را برمی گرداند.
اگر در حین خواندن یا تجزیه خطایی رخ دهد، بلوک catch کار را می گیرد. خطا را با نام فایل و جزئیات ثبت می کند و سپس یک آرایه خالی به جای شی JSON مورد انتظار برمی گرداند.
مرحله 3: تابع اصلی را اجرا کنید
مرحله بعدی ایجاد یک تابع اصلی است که در آن از روش تعریف شده در بالا استفاده می کنیم و داده های دو فایل را برای ایجاد یک فایل bio.json ترکیب می کنیم.
async function main ( ) { try { const names = await readJSONFile( "names.json" ); const addresses = await readJSONFile( "address.json" ); const bioData = names.map( ( name ) => { const matchingAddress = addresses.find( ( address ) => address.id === name.id ); return { ...name, ...matchingAddress }; }); await fs.writeFile( "bio.json" , JSON .stringify(bioData, null , 2 )); console .log( "bio.json created successfully!" ); } catch (error) { console .error( "Error combining data:" , error); } }
در تابع main ابتدا دو فایل JSON به نام names.json
و address.json
را با استفاده از تابع readJSONFile می خوانیم. هر دو فراخوانی readJSONFile از انتظار استفاده میکنند، پس این تابع قبل از ادامه کار منتظر میماند تا هر دو فایل خوانده شوند.
در مرحله بعد، با استفاده از یک نقشه، هر name
را تکرار می کنیم و برای هر کدام یک bioData
جدید ایجاد می کنیم. در داخل حلقه، یک address
منطبق را از مجموعه آدرس ها بر اساس فهرست با استفاده از find جستجو می کند.
جستجو name.id
با هر address.id
مقایسه میکند تا زمانی که مطابقت پیدا کند. اگر مطابقت پیدا شود، تابع اطلاعات هر دو فایل را ترکیب می کند. از عملگر spread (...) برای ادغام تمام خصوصیات از هر دو شی در یک شی جدید bioData
استفاده می کند. اگر آدرس منطبقی پیدا نشد، شی bioData
فقط اطلاعات نام را خواهد داشت.
هنگامی که تمام اشیاء bioData
آماده شدند، تابع آنها را به عنوان یک فایل JSON جدید به نام bio.json
با استفاده از fs.writeFile
می نویسد. این فرآیند نوشتن همچنین از انتظار استفاده میکند تا اطمینان حاصل شود که فایل قبل از ادامه کار ایجاد شده است.
بلوک try اجرای روان را تضمین می کند، در حالی که بلوک catch از هرگونه خطا مانند فایل های از دست رفته یا داده های نادرست مراقبت می کند. اگر خطایی رخ دهد، یک پیام خطای عمومی و جزئیات خطای خاص برای اشکال زدایی ثبت می شود.
کد کامل
کد تکمیل شده ما به شکل زیر است:
const fs = require ( "fs" ).promises; async function readJSONFile ( filename ) { try { const data = await fs.readFile(filename, "utf8" ); return JSON .parse(data); } catch (error) { console .error( `Error reading ${filename} : ${error} ` ); return []; } } async function main ( ) { try { const names = await readJSONFile( "names.json" ); const addresses = await readJSONFile( "address.json" ); const bioData = names.map( ( name ) => { const matchingAddress = addresses.find( ( address ) => address.id === name.id ); return { ...name, ...matchingAddress }; }); await fs.writeFile( "bio.json" , JSON .stringify(bioData, null , 2 )); console .log( "bio.json created successfully!" ); } catch (error) { console .error( "Error combining data:" , error); } } // Execute the main method main();
ما می توانیم برنامه را با استفاده از دستور زیر اجرا کنیم:
node app.js
هنگامی که برنامه اجرا می شود، اگر همه چیز به خوبی پیش برود، گزارش های زیر را در ترمینال مشاهده می کنیم:
bio.json created successfully!
این نشان می دهد که فایل bio.json با موفقیت ایجاد شده است. محتوای داخل فایل باید به شکل زیر باشد:
[ { "id" : 1 , "name" : "Alice" , "address" : "123 Main St" }, { "id" : 2 , "name" : "Bob" , "address" : "456 Elm St" }, { "id" : 3 , "name" : "Charlie" , "address" : "789 Oak St" } ]
راه های خواندن فایل ها در Node.js
برای خواندن فایلها در Node.js، بیشتر از دو روش اصلی استفاده میکنیم: fs.readFile()
و fs.readFileSync()
. تفاوت در ماهیت همزمان و ناهمزمان آنها نهفته است.
روش fs.readFile()
متد fs.readFile()
در Node.js ناهمزمان است. محتوای کل فایل را بدون مسدود کردن سایر عملیات می خواند. این آن را برای سناریوهایی که عملیات I/O غیر مسدود ضروری هستند، مناسب می کند.
به زبان ساده، این تابع به سایر عملیات ها اجازه می دهد تا زمانی که خواندن انجام می شود ادامه پیدا کنند. سه پارامتر زیر را می پذیرد:
path: مسیر فایلی که باید خوانده شود.
encoding: اختیاری، رمزگذاری فایل را مشخص می کند (به عنوان مثال، "utf8"). در صورت عدم ارائه، به طور پیش فرض به "utf8" می رسد.
تابع callback: اختیاری، تابعی که هنگام خواندن فایل فراخوانی می شود. تابع سه آرگومان دریافت می کند: خطا، داده و بافر.
بیایید به یک مثال نگاه کنیم:
const fs = require ( "fs" ); fs.readFile( "data.txt" , "utf8" , ( err, data ) => { if (err) { console .error(err); } else { console .log(data); // data will be a string containing the content of the file } });
روش fs.readFileSync()
متد fs.readFileSync()
همزمان است. محتوای فایل را به صورت همزمان می خواند و اجرای بیشتر را تا زمانی که فایل به طور کامل خوانده شود متوقف می کند. این روش در سناریوهایی که نیاز به پردازش همزمان داریم مفید است.
فقط دو پارامتر را می طلبد:
path: مسیر فایلی که باید خوانده شود
encoding: اختیاری، رمزگذاری فایل را مشخص می کند (به عنوان مثال، "utf8"). در صورت عدم ارائه، به طور پیش فرض به "utf8" می رسد.
بیایید به یک مثال نگاه کنیم:
const fs = require ( "fs" ); try { const data = fs.readFileSync( "data.txt" , "utf8" ); console .log(data); // data will be a string containing the content of the file } catch (err) { console .error(err); }
fs.readFile()
در مقابل fs.readFileSync()
برای درک تفاوت بین متدهای Nodejs readFile
و readFileSync
، دو برنامه می نویسیم و جریان اجرای آنها را نظارت می کنیم.
بیایید با متد fs.readFile()
شروع کنیم.
const fs = require ( "fs" ); fs.readFile( "example.txt" , "utf8" , ( err, data ) => { console .log( "Content from readFile:" , data); }); console .log( "Completed reading file content asynchronously" );
خروجی:
Completed reading file content asynchronously Content from readFile: freeCodeCamp is awesome!
به دلیل ماهیت ناهمزمان fs.readFile()
، کد بعد از fs.readFile()
منتظر پایان عملیات خواندن فایل نمی ماند. پس پیام «محتوای فایل خواندن به طور همزمان کامل شد» بلافاصله در کنسول ثبت میشود و نشان میدهد که کد بعدی بدون منتظر ماندن برای تکمیل فایل خوانده شده به اجرا ادامه میدهد.
در نهایت، زمانی که عملیات خواندن فایل به پایان می رسد، تابع callback محتوای فایل را اجرا و ثبت می کند.
در ادامه، اجرای متد fs.readFileSync()
را می بینیم.
const fs = require ( "fs" ); const data = fs.readFileSync( "data.txt" , "utf8" ); console .log( "Content from readFileSync:" , data); console .log( "Completed reading file content synchronously" );
خروجی:
Content from readFileSync: freeCodeCamp is awesome! Completed reading file content synchronously
در مقابل، fs.readFileSync()
فایل data.txt را به صورت همزمان می خواند و اجرای کد بیشتر را تا زمانی که فایل به طور کامل خوانده شود مسدود می کند. در نتیجه، اجرای کد تنها پس از پایان عملیات خواندن فایل ادامه مییابد.
به همین دلیل، پس از خواندن موفقیتآمیز محتوای فایل، پیام «محتوای فایل به طور همزمان کامل شد» ثبت میشود.
اکنون تفاوت بین این دو روش را می دانیم. درک این تفاوت مهم است زیرا بر جریان برنامه تأثیر می گذارد، به ویژه در سناریوهایی که زمان بندی و عملیات مسدود کردن ملاحظات مهم در برنامه های Node.js هستند.
نحوه خواندن یک فایل متنی
خواندن یک فایل متنی در Node.js بسیار ساده است و ما در طول آموزش این کار را انجام داده ایم. بیایید در نظر بگیریم که فایلی به نام message.txt با محتوای زیر داریم:
Learn Node.js with freeCodeCamp
حال قصد داریم محتویات این فایل را بخوانیم. ما می توانیم این کار را به این صورت انجام دهیم:
const fs = require ( "fs" ); fs.readFile( "message.txt" , "utf8" , ( err, data ) => { if (err) { console .log(err); } else { console .log(data); } });
تابع callback محتوای فایل را در یک متغیر داده برمی گرداند. از آنجایی که رمزگذاری را روی "utf8" تنظیم کردیم، مقدار داده ها یک رشته است. پس می توانیم عملیات رشته ای را روی متغیر داده انجام دهیم.
const fs = require ( "fs" ); fs.readFile( "message.txt" , "utf8" , ( err, data ) => { if (err) { console .log(err); } else { let splittedWords = data.split( " " ); console .log(splittedWords); } });
در کد بالا، متغیر داده را با استفاده از یک فاصله تقسیم می کنیم. پس splittedWords یک آرایه رشته ای خواهد بود که حاوی مقدار زیر است:
[ 'Learn' , 'Node.js' , 'with' , 'freeCodeCamp' ]
نحوه خواندن فایل های HTML
خواندن فایلهای HTML از روشی مشابه برای خواندن فایلهای متنی در Node.js پیروی میکند. ما می توانیم از ماژول fs
برای خواندن فایل های HTML استفاده کنیم:
const fs = require ( "fs" ); fs.readFile( "index.html" , "utf8" , ( err, data ) => { if (err) { console .log(err); } else { console .log(data); } });
سپس میتوانیم از محتوای HTML برای پردازش بیشتر، مانند رندر کردن آن با بسته http
Node.js استفاده کنیم.
نحوه خواندن فایل ها با URL
خواندن فایل ها با URL در Node.js شامل مراحل اضافی فراتر از ماژول fs بومی است. به طور معمول، ما باید از ماژول های اضافی مانند http
یا axios
برای واکشی محتوای فایل از یک URL استفاده کنیم.
const fs = require ( "fs" ); const https = require ( "https" ); const file = fs.createWriteStream( "data.txt" ); https.get( "https://example-files.online-convert.com/document/txt/example.txt" , ( response ) => { var stream = response.pipe(file); stream.on( "finish" , function ( ) { console .log( "done" ); }); } );
ابتدا، یک جریان قابل نوشتن به نام فایل را تنظیم می کنیم که با فایل محلی data.txt مرتبط است. سپس از ماژول https
Node.js برای انجام یک درخواست HTTP GET به URL مشخص شده استفاده می کنیم. هنگامی که ما پاسخی از سرور دریافت می کنیم، متد get یک تابع تماس را راه اندازی می کند.
در داخل callback، اسکریپت پاسخ را مستقیماً به جریان قابل نوشتن ارسال می کند. این عملیات به طور موثر داده های دریافت شده از سرور راه دور را به فایل محلی data.txt هدایت می کند و اساساً محتوا را همزمان دانلود و می نویسد.
در نهایت، یک شنونده رویداد برای رویداد "پایان" در جریان راه اندازی کردیم. این رویداد زمانی فعال می شود که تمام داده ها با موفقیت در فایل نوشته شوند. پس از تکمیل، اسکریپت به کنسول "انجام شد" ثبت می شود که نشان دهنده موفقیت آمیز دانلود و نوشتن فایل است.
نحوه خواندن یک فایل JSON
قبلاً دیده ایم که چگونه می توانیم یک فایل JSON را با استفاده از ماژول fs بخوانیم. فرض کنید میخواهیم فایل bio.json را که قبلاً ایجاد کردهایم بخوانیم. داده های آن مانند زیر است:
[ { "id" : 1 , "name" : "Alice" , "address" : "123 Main St" }, { "id" : 2 , "name" : "Bob" , "address" : "456 Elm St" }, { "id" : 3 , "name" : "Charlie" , "address" : "789 Oak St" } ]
در Node.js، JSON را به این صورت می خوانیم:
const fs = require ( "fs" ); fs.readFile( "bio.json" , "utf8" , ( err, data ) => { if (err) { console .log(err); } else { console .log(data); } });
با این کار، داده های JSON ما در متغیر داده به عنوان یک رشته ذخیره می شود. در صورت تمایل می توانیم از آن برای پردازش بیشتر استفاده کنیم. فرض کنید، قصد داریم جزئیات کاربر را چاپ کنیم:
const fs = require ( "fs" ); fs.readFile( "bio.json" , "utf8" , ( err, data ) => { if (err) { console .log(err); } else { const users = JSON .parse(data); users.forEach( ( user ) => { console .log( ` ${user.name} with ID ${user.id} lives at ${user.address} ` ); }); } });
خروجی:
Alice with ID 1 lives at 123 Main St Bob with ID 2 lives at 456 Elm St Charlie with ID 3 lives at 789 Oak St
در کد بالا، ابتدا متغیر داده رشته را به JSON تجزیه و در متغیر users
ذخیره می کنیم. سپس روی متغیر users
حلقه می زنیم تا پیام مورد نیاز را ثبت کنیم.
fs.promises
fs.promises
مجموعه ای از توابع ناهمزمان را برای تعامل با سیستم فایل در Node.js فراهم می کند. این توابع بر اساس وعدهها هستند و روشی خوانا و کارآمدتر برای مدیریت عملیات ناهمزمان در مقایسه با تماسهای برگشتی ارائه میدهند.
با fs.promises
، ما نیازی به اضافه کردن تماسهای تودرتو نداریم - به این معنی که میتوانیم از جهنم پاسخ به تماس جلوگیری کنیم.
یک عملیات readFile اولیه با fs.promises
به شکل زیر است:
const fs = require ( "fs" ).promises; async function readTextFile ( ) { try { const data = await fs.readFile( "data.txt" , "utf8" ); console .log(data); } catch (err) { console .error(err); } } readTextFile();
بسته بندی
در این آموزش، تکنیک های ضروری برای مدیریت فایل ها در Node.js با کمک ماژول fs را تحلیل کرده ایم.
از درک خواندن همزمان و ناهمزمان فایلها با روشهایی مانند fs.readFile()
و fs.readFileSync()
گرفته تا پردازش فرمتهای فایل مختلف مانند متن، HTML، JSON و حتی خواندن فایلها از URL، ما مجموعهای از قابلیتها را پوشش دادهایم. ما همچنین در مورد fs.promises، که روشی زیباتر برای مدیریت عملیات فایل با استفاده از توابع ناهمزمان است، یاد گرفتیم.
سوالات متداول (سؤالات متداول)
1. چگونه می توانم یک فایل را به صورت ناهمزمان در Node.js بخوانم؟
عمدتاً دو راه برای خواندن یک فایل به صورت ناهمزمان در Node.js وجود دارد: استفاده از fs.readFile()
و استفاده از fs.promises
.
متد fs.readFile()
از callbacks برای مدیریت عملیات استفاده می کند. ما یک تابع فراخوانی ارائه می دهیم که با داده های فایل (یا یک خطا) پس از اتمام خواندن فراخوانی می شود.
اما fs.promises
یک رویکرد مبتنی بر وعده ارائه می دهد. میتوانیم از تابع readFile
با انتظار برای پایان خواندن و سپس دسترسی مستقیم به دادهها استفاده کنیم.
2. چگونه می توانم قبل از خواندن یا نوشتن در Node.js وجود فایل را تحلیل کنم؟
دو روش برای تحلیل وجود فایل وجود دارد: استفاده از fs.stat
و استفاده از fs.promises.access
.
روش fs.stat
به طور همزمان تحلیل میکند که آیا فایلی وجود دارد یا خیر و اطلاعات مربوط به آن مانند اندازه و زمان دسترسی را برمیگرداند. متد fs.promises.access
به صورت ناهمزمان تحلیل میکند که آیا فایلی وجود دارد یا خیر و قولی را برمیگرداند که بر اساس وجود فایل رفع یا رد شود.
3. چگونه می توانم خطاها را هنگام خواندن یا نوشتن فایل ها در Node.js مدیریت کنم؟
برای رسیدگی به خطاها در حین خواندن یا نوشتن فایلها در Node.js، میتوانیم از تماسها یا وعدههای اول خطا به همراه بلوکهای try-catch استفاده کنیم.
ارسال نظر