ماژول File System در Node.js: مدیریت فایل‌ها و جریان‌ها

ماژول node:fs در Node.js امکان تعامل با سیستم فایل را فراهم می‌کند. این ماژول بر اساس توابع استاندارد POSIX طراحی شده و سه شکل اصلی برای عملیات‌ها ارائه می‌دهد: Promise-based، Callback-based و Synchronous. هرکدام بسته به نیازهای عملکردی و معماری برنامه کاربرد خاص خود را دارند.

fs/promisesCallback APIsSynchronous APIsFileHandlecreateReadStream / createWriteStream

~18 دقیقه مطالعه • بروزرسانی ۸ دی ۱۴۰۴

1. استفاده از Promise APIs


نسخهٔ Promise از ماژول fs عملیات‌های فایل را به‌صورت غیرهمزمان و با بازگشت Promise انجام می‌دهد.


const { unlink } = require('node:fs/promises');
(async function(path) {
  try {
    await unlink(path);
    console.log(`successfully deleted ${path}`);
  } catch (error) {
    console.error('error:', error.message);
  }
})('/tmp/hello');

2. استفاده از Callback APIs


نسخهٔ Callback عملیات‌ها را با یک تابع تکمیل‌کننده انجام می‌دهد. آرگومان اول همیشه خطا است.


const { unlink } = require('node:fs');
unlink('/tmp/hello', (err) => {
  if (err) throw err;
  console.log('successfully deleted /tmp/hello');
});

3. استفاده از Synchronous APIs


نسخهٔ همزمان اجرای جاوااسکریپت را تا پایان عملیات متوقف می‌کند. خطاها فوراً با try...catch مدیریت می‌شوند.


const { unlinkSync } = require('node:fs');
try {
  unlinkSync('/tmp/hello');
  console.log('successfully deleted /tmp/hello');
} catch (err) {
  console.error(err);
}

4. FileHandle


کلاس FileHandle یک wrapper برای توصیفگر فایل است که توسط fsPromises.open() ایجاد می‌شود. این کلاس یک EventEmitter است و متدهای مختلفی برای مدیریت فایل ارائه می‌دهد.


  • filehandle.close(): بستن فایل.
  • filehandle.appendFile(): نوشتن داده در فایل.
  • filehandle.chmod(): تغییر مجوزها.
  • filehandle.chown(): تغییر مالکیت.

5. جریان‌های خواندن و نوشتن


  • filehandle.createReadStream(): ایجاد جریان خواندن با گزینه‌هایی مانند start و end.
  • filehandle.createWriteStream(): ایجاد جریان نوشتن با گزینه‌هایی مانند start و flush.

این جریان‌ها امکان پردازش داده‌های بزرگ بدون بارگذاری کامل در حافظه را فراهم می‌کنند.


6. متدهای خواندن


  • filehandle.read(): خواندن داده در یک buffer.
  • filehandle.readFile(): خواندن کل محتوای فایل.
  • filehandle.readLines(): خواندن فایل خط‌به‌خط با استفاده از readline.
  • filehandle.readableWebStream(): بازگرداندن یک ReadableStream سازگار با وب.

7. مدیریت همزمانی


عملیات‌های Promise-based از threadpool داخلی Node.js استفاده می‌کنند و thread-safe نیستند. بنابراین هنگام انجام تغییرات همزمان روی یک فایل باید دقت شود تا از فساد داده جلوگیری شود.


نتیجه‌گیری


ماژول fs در Node.js ابزارهای قدرتمندی برای مدیریت فایل‌ها و جریان‌ها ارائه می‌دهد. انتخاب بین Promise، Callback یا Synchronous به نیازهای عملکردی و معماری برنامه بستگی دارد. استفادهٔ صحیح از کلاس FileHandle و جریان‌ها باعث افزایش کارایی و جلوگیری از نشت منابع می‌شود.


1. filehandle.readv()


این متد داده‌ها را از فایل خوانده و در چندین Buffer یا TypedArray ذخیره می‌کند.


  • buffers: آرایه‌ای از Buffer یا TypedArray.
  • position: موقعیت شروع خواندن در فایل.

نتیجه شامل تعداد بایت‌های خوانده‌شده و مرجع به آرایهٔ ورودی است.


2. filehandle.stat()


اطلاعات آماری فایل (مانند اندازه، زمان آخرین تغییر و مجوزها) را بازمی‌گرداند. گزینهٔ bigint می‌تواند مقادیر عددی را به‌صورت BigInt ارائه دهد.


3. filehandle.sync()


تمام داده‌های در صف را به دیسک همگام‌سازی می‌کند. این متد مشابه fsync(2) در POSIX است.


4. filehandle.truncate(len)


فایل را به طول مشخص‌شده کوتاه می‌کند. اگر فایل بزرگ‌تر باشد، فقط بخش ابتدایی باقی می‌ماند؛ اگر کوتاه‌تر باشد، با بایت‌های صفر ('\0') پر می‌شود.


import { open } from 'node:fs/promises';
let fh = await open('temp.txt', 'r+');
await fh.truncate(4);
await fh.close();

5. filehandle.utimes(atime, mtime)


زمان‌های دسترسی (atime) و تغییر (mtime) فایل را تغییر می‌دهد.


6. متدهای نوشتن


  • filehandle.write(buffer, offset, length, position): نوشتن داده از Buffer.
  • filehandle.write(buffer, options): نسخهٔ جدید با شیء options.
  • filehandle.write(string, position, encoding): نوشتن رشته با encoding مشخص.
  • filehandle.writeFile(data, options): نوشتن کل داده در فایل (جایگزینی فایل موجود).
  • filehandle.writev(buffers, position): نوشتن چندین Buffer یا TypedArray به فایل.

توجه: استفادهٔ همزمان از متدهای write بدون انتظار برای پایان Promise ناامن است. در این موارد باید از createWriteStream() استفاده شود.


7. filehandle[Symbol.asyncDispose]()


این متد فایل را می‌بندد و یک Promise بازمی‌گرداند که پس از بسته‌شدن فایل fulfilled می‌شود.


8. fsPromises.access()


دسترسی به فایل یا پوشه را بررسی می‌کند. حالت mode می‌تواند ترکیبی از R_OK، W_OK و X_OK باشد.


import { access, constants } from 'node:fs/promises';
try {
  await access('/etc/passwd', constants.R_OK | constants.W_OK);
  console.log('can access');
} catch {
  console.error('cannot access');
}

توجه: استفاده از access() قبل از open() توصیه نمی‌شود زیرا ممکن است شرایط فایل بین دو فراخوانی تغییر کند.


نتیجه‌گیری


کلاس FileHandle و متدهای fs/promises ابزارهای قدرتمندی برای مدیریت پیشرفتهٔ فایل‌ها در Node.js هستند. این متدها امکان خواندن و نوشتن انعطاف‌پذیر، تغییر اندازه و زمان فایل، همگام‌سازی داده‌ها و بررسی دسترسی‌ها را فراهم می‌کنند. استفادهٔ صحیح از این متدها باعث افزایش کارایی و جلوگیری از خطاهای همزمانی می‌شود.


1. fsPromises.appendFile()


به‌صورت غیرهمزمان داده‌ای را به انتهای فایل اضافه می‌کند. اگر فایل وجود نداشته باشد، ایجاد می‌شود.


import { appendFile } from 'node:fs/promises';
await appendFile('log.txt', 'New entry\n');

2. fsPromises.chmod() و fsPromises.chown()


  • chmod(path, mode): تغییر مجوزهای فایل.
  • chown(path, uid, gid): تغییر مالکیت فایل.

3. fsPromises.copyFile()


کپی یک فایل به مقصد مشخص. گزینه‌ها شامل COPYFILE_EXCL برای جلوگیری از بازنویسی و COPYFILE_FICLONE برای استفاده از Copy-on-Write هستند.


import { copyFile, constants } from 'node:fs/promises';
await copyFile('source.txt', 'dest.txt', constants.COPYFILE_EXCL);

4. fsPromises.cp()


کپی پوشه‌ها و ساختارهای کامل به‌صورت بازگشتی. گزینه‌ها شامل recursive، preserveTimestamps و filter هستند.


5. fsPromises.glob()


جستجوی فایل‌ها با الگوهای glob. نتیجه یک AsyncIterator است که مسیرهای فایل‌های مطابق الگو را بازمی‌گرداند.


import { glob } from 'node:fs/promises';
for await (const entry of glob('**/*.js')) {
  console.log(entry);
}

6. fsPromises.link()


ایجاد یک لینک سخت از مسیر موجود به مسیر جدید.


7. fsPromises.lstat()


بازگرداندن اطلاعات آماری یک لینک نمادین بدون دنبال‌کردن مقصد آن.


8. fsPromises.mkdir()


ایجاد پوشه جدید. گزینهٔ recursive امکان ایجاد پوشه‌های والد را فراهم می‌کند.


import { mkdir } from 'node:fs/promises';
await mkdir('project/data', { recursive: true });

9. fsPromises.mkdtemp()


ایجاد پوشهٔ موقت با نام یکتا. شش کاراکتر تصادفی به انتهای prefix اضافه می‌شود.


10. fsPromises.mkdtempDisposable()


ایجاد پوشهٔ موقت همراه با شیء disposable که متد remove() یا [Symbol.asyncDispose] برای حذف پوشه دارد.


نتیجه‌گیری


متدهای پیشرفتهٔ fsPromises در Node.js ابزارهای قدرتمندی برای مدیریت فایل‌ها و پوشه‌ها ارائه می‌دهند. این متدها امکان افزودن داده، تغییر مجوزها، کپی فایل‌ها و پوشه‌ها، جستجو با الگو و ایجاد پوشه‌های موقت را فراهم می‌کنند. استفادهٔ صحیح از این متدها باعث افزایش کارایی و سادگی در پروژه‌های بزرگ می‌شود.


1. fsPromises.opendir()


پوشه‌ای را به‌صورت غیرهمزمان باز می‌کند و یک fs.Dir بازمی‌گرداند که می‌تواند با AsyncIterator پیمایش شود.


import { opendir } from 'node:fs/promises';
const dir = await opendir('./');
for await (const dirent of dir) {
  console.log(dirent.name);
}

2. fsPromises.readdir()


محتوای پوشه را به‌صورت آرایه بازمی‌گرداند. گزینهٔ withFileTypes می‌تواند اشیاء Dirent بازگرداند.


3. fsPromises.readFile()


کل محتوای فایل را می‌خواند و به‌صورت Buffer یا رشته بازمی‌گرداند. امکان استفاده از AbortSignal برای لغو عملیات وجود دارد.


4. fsPromises.readlink()


محتوای یک لینک نمادین را بازمی‌گرداند.


5. fsPromises.realpath()


مسیر واقعی فایل یا پوشه را بازمی‌گرداند.


6. fsPromises.rename()


نام یک فایل یا پوشه را تغییر می‌دهد.


7. fsPromises.rmdir() و fsPromises.rm()


rmdir() پوشه را حذف می‌کند. rm() فایل‌ها و پوشه‌ها را با گزینه‌های recursive و force حذف می‌کند.


8. fsPromises.stat() و fsPromises.statfs()


اطلاعات آماری فایل یا سیستم فایل را بازمی‌گرداند.


9. fsPromises.symlink()


یک لینک نمادین ایجاد می‌کند. در ویندوز نوع لینک می‌تواند file، dir یا junction باشد.


10. fsPromises.truncate()


فایل را کوتاه یا بلند می‌کند تا به طول مشخص برسد.


11. fsPromises.unlink()


یک فایل یا لینک نمادین را حذف می‌کند.


12. fsPromises.utimes()


زمان‌های دسترسی (atime) و تغییر (mtime) فایل را تغییر می‌دهد.


13. fsPromises.watch()


تغییرات فایل یا پوشه را مانیتور می‌کند و یک AsyncIterator از رویدادها بازمی‌گرداند.


import { watch } from 'node:fs/promises';
const watcher = watch('./file.txt');
for await (const event of watcher) {
  console.log(event);
}

14. fsPromises.writeFile()


داده‌ای را به فایل می‌نویسد و در صورت وجود فایل آن را جایگزین می‌کند. امکان لغو با AbortSignal وجود دارد.


نتیجه‌گیری


ماژول fs/promises در Node.js ابزارهای قدرتمندی برای مدیریت فایل‌ها و پوشه‌ها ارائه می‌دهد. این متدها امکان خواندن، نوشتن، حذف، تغییر مسیر و مانیتورینگ تغییرات را فراهم می‌کنند. استفادهٔ صحیح از این متدها باعث افزایش کارایی و سادگی در پروژه‌های بزرگ می‌شود.


1. fs.appendFile()


به‌صورت غیرهمزمان داده‌ای را به انتهای فایل اضافه می‌کند. اگر فایل وجود نداشته باشد، ایجاد می‌شود.


import { appendFile } from 'node:fs';
appendFile('message.txt', 'data to append', (err) => {
  if (err) throw err;
  console.log('Data appended!');
});

2. fs.chmod()


مجوزهای فایل را تغییر می‌دهد. مقدار mode یک bitmask عددی است که با استفاده از مقادیر fs.constants ساخته می‌شود.


import { chmod } from 'node:fs';
chmod('my_file.txt', 0o775, (err) => {
  if (err) throw err;
  console.log('Permissions changed!');
});

3. fs.chown()


مالک و گروه فایل را تغییر می‌دهد.


4. fs.close()


یک File Descriptor باز را می‌بندد. اگر fd در حال استفاده باشد، رفتار نامشخص خواهد بود.


5. fs.copyFile()


یک فایل را به مقصد مشخص کپی می‌کند. گزینه‌ها شامل COPYFILE_EXCL برای جلوگیری از بازنویسی و COPYFILE_FICLONE برای Copy-on-Write هستند.


import { copyFile, constants } from 'node:fs';
copyFile('source.txt', 'dest.txt', constants.COPYFILE_EXCL, (err) => {
  if (err) throw err;
  console.log('File copied!');
});

6. fs.cp()


پوشه‌ها و ساختارهای کامل را به‌صورت بازگشتی کپی می‌کند. گزینه‌ها شامل recursive و preserveTimestamps هستند.


7. fs.createReadStream()


یک جریان خواندن ایجاد می‌کند. می‌توان محدوده‌ای از فایل را با گزینه‌های start و end خواند.


import { createReadStream } from 'node:fs';
createReadStream('sample.txt', { start: 90, end: 99 });

8. fs.createWriteStream()


یک جریان نوشتن ایجاد می‌کند. امکان نوشتن داده در موقعیت مشخص فایل وجود دارد. گزینهٔ autoClose تعیین می‌کند که پس از پایان یا خطا فایل بسته شود.


نتیجه‌گیری


ماژول fs در Node.js با متدهای Callback-based ابزارهای قدرتمندی برای مدیریت فایل‌ها و پوشه‌ها ارائه می‌دهد. این متدها امکان افزودن داده، تغییر مجوزها، کپی فایل‌ها و کار با جریان‌ها را فراهم می‌کنند. استفادهٔ صحیح از این متدها باعث افزایش کارایی و جلوگیری از نشت منابع در پروژه‌های بزرگ می‌شود.


1. fs.exists()


بررسی می‌کند که آیا فایل یا پوشه در مسیر مشخص وجود دارد یا خیر. این متد منسوخ شده و استفاده از fs.access() یا fs.stat() توصیه می‌شود. دلیل: Callback آن فقط یک مقدار بولی دارد و با الگوی استاندارد Node.js سازگار نیست.


2. fs.fchmod() و fs.fchown()


  • fchmod(fd, mode): تغییر مجوزهای فایل با استفاده از File Descriptor.
  • fchown(fd, uid, gid): تغییر مالک و گروه فایل.

3. fs.fdatasync() و fs.fsync()


این متدها داده‌های در صف را به دیسک همگام‌سازی می‌کنند. fdatasync() فقط داده‌ها را همگام می‌کند، در حالی که fsync() داده‌ها و متادیتا را همگام می‌کند.


4. fs.fstat()


اطلاعات آماری فایل را بر اساس File Descriptor بازمی‌گرداند. گزینهٔ bigint می‌تواند مقادیر عددی را به‌صورت BigInt ارائه دهد.


5. fs.ftruncate()


فایل را به طول مشخص کوتاه یا بلند می‌کند. اگر فایل بزرگ‌تر باشد، فقط بخش ابتدایی باقی می‌ماند؛ اگر کوتاه‌تر باشد، با بایت‌های صفر ('\0') پر می‌شود.


6. fs.futimes()


زمان‌های دسترسی (atime) و تغییر (mtime) فایل را بر اساس File Descriptor تغییر می‌دهد.


7. fs.glob()


فایل‌ها را بر اساس الگوهای glob جستجو می‌کند. نتیجه شامل مسیرهای فایل‌های مطابق الگو است.


import { glob } from 'node:fs';
glob('**/*.js', (err, matches) => {
  if (err) throw err;
  console.log(matches);
});

8. fs.lchmod(), fs.lchown(), fs.lutimes()


  • lchmod(): تغییر مجوزهای لینک نمادین (فقط در macOS، منسوخ).
  • lchown(): تغییر مالک لینک نمادین.
  • lutimes(): تغییر زمان‌های لینک نمادین بدون دنبال‌کردن مقصد.

9. fs.link()


ایجاد یک لینک سخت از مسیر موجود به مسیر جدید.


10. fs.lstat()


اطلاعات آماری لینک نمادین را بازمی‌گرداند، نه فایل مقصد آن. مشابه stat() اما برای خود لینک.


نتیجه‌گیری


ماژول fs در Node.js با متدهای Callback-based ابزارهای قدرتمندی برای مدیریت پیشرفتهٔ فایل‌ها و پوشه‌ها ارائه می‌دهد. برخی متدها منسوخ شده‌اند و جایگزین‌های جدیدتر توصیه می‌شوند. استفادهٔ صحیح از این متدها باعث افزایش کارایی و جلوگیری از خطاهای همزمانی در پروژه‌های بزرگ می‌شود.


1. fs.exists()


بررسی می‌کند که آیا فایل یا پوشه در مسیر مشخص وجود دارد یا خیر. این متد منسوخ شده و استفاده از fs.access() یا fs.stat() توصیه می‌شود. دلیل: Callback آن فقط یک مقدار بولی دارد و با الگوی استاندارد Node.js سازگار نیست.


2. fs.fchmod() و fs.fchown()


  • fchmod(fd, mode): تغییر مجوزهای فایل با استفاده از File Descriptor.
  • fchown(fd, uid, gid): تغییر مالک و گروه فایل.

3. fs.fdatasync() و fs.fsync()


این متدها داده‌های در صف را به دیسک همگام‌سازی می‌کنند. fdatasync() فقط داده‌ها را همگام می‌کند، در حالی که fsync() داده‌ها و متادیتا را همگام می‌کند.


4. fs.fstat()


اطلاعات آماری فایل را بر اساس File Descriptor بازمی‌گرداند. گزینهٔ bigint می‌تواند مقادیر عددی را به‌صورت BigInt ارائه دهد.


5. fs.ftruncate()


فایل را به طول مشخص کوتاه یا بلند می‌کند. اگر فایل بزرگ‌تر باشد، فقط بخش ابتدایی باقی می‌ماند؛ اگر کوتاه‌تر باشد، با بایت‌های صفر ('\0') پر می‌شود.


6. fs.futimes()


زمان‌های دسترسی (atime) و تغییر (mtime) فایل را بر اساس File Descriptor تغییر می‌دهد.


7. fs.glob()


فایل‌ها را بر اساس الگوهای glob جستجو می‌کند. نتیجه شامل مسیرهای فایل‌های مطابق الگو است.


import { glob } from 'node:fs';
glob('**/*.js', (err, matches) => {
  if (err) throw err;
  console.log(matches);
});

8. fs.lchmod(), fs.lchown(), fs.lutimes()


  • lchmod(): تغییر مجوزهای لینک نمادین (فقط در macOS، منسوخ).
  • lchown(): تغییر مالک لینک نمادین.
  • lutimes(): تغییر زمان‌های لینک نمادین بدون دنبال‌کردن مقصد.

9. fs.link()


ایجاد یک لینک سخت از مسیر موجود به مسیر جدید.


10. fs.lstat()


اطلاعات آماری لینک نمادین را بازمی‌گرداند، نه فایل مقصد آن. مشابه stat() اما برای خود لینک.


نتیجه‌گیری


ماژول fs در Node.js با متدهای Callback-based ابزارهای قدرتمندی برای مدیریت پیشرفتهٔ فایل‌ها و پوشه‌ها ارائه می‌دهد. برخی متدها منسوخ شده‌اند و جایگزین‌های جدیدتر توصیه می‌شوند. استفادهٔ صحیح از این متدها باعث افزایش کارایی و جلوگیری از خطاهای همزمانی در پروژه‌های بزرگ می‌شود.


1. fs.readFile()


این متد کل محتوای فایل را به‌صورت غیرهمزمان می‌خواند و در Callback بازمی‌گرداند.


  • path: مسیر فایل یا File Descriptor.
  • options: شامل encoding و flag.
  • callback(err, data): دادهٔ خوانده‌شده یا خطا.

import { readFile } from 'node:fs';
readFile('/etc/passwd', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

اگر encoding مشخص نشود، داده به‌صورت Buffer بازمی‌گردد. همچنین امکان لغو عملیات با AbortSignal وجود دارد.


نکات عملکردی


  • برای فایل‌های بزرگ، استفاده از fs.createReadStream() توصیه می‌شود تا مصرف حافظه کاهش یابد.
  • در فایل‌های معمولی، هر بار 512 KiB داده خوانده می‌شود؛ در فایل‌های خاص مانند Pipe، هر بار 64 KiB.
  • برای خواندن سریع‌تر، می‌توان از fs.read() استفاده کرد و مدیریت خواندن را به‌صورت دستی انجام داد.

2. fs.readlink()


این متد مسیر مقصد یک لینک نمادین را بازمی‌گرداند.


  • path: مسیر لینک نمادین.
  • options: شامل encoding.
  • callback(err, linkString): مسیر مقصد یا خطا.

import { readlink } from 'node:fs';
readlink('/path/to/symlink', (err, linkString) => {
  if (err) throw err;
  console.log('Link points to:', linkString);
});

اگر encoding برابر با buffer باشد، مسیر مقصد به‌صورت Buffer بازگردانده می‌شود.


نتیجه‌گیری


متدهای fs.readFile() و fs.readlink() ابزارهای قدرتمندی برای خواندن داده‌ها و مدیریت لینک‌های نمادین در Node.js هستند. انتخاب بین آن‌ها به نیاز پروژه بستگی دارد: readFile() برای بارگذاری کامل محتوا و readlink() برای مدیریت ساختار فایل‌ها و لینک‌ها. استفادهٔ صحیح از این متدها باعث افزایش کارایی و سادگی در پروژه‌های بزرگ می‌شود.


1. fs.readv()


داده‌ها را از فایل مشخص‌شده توسط File Descriptor خوانده و در چندین Buffer یا TypedArray ذخیره می‌کند. Callback شامل سه آرگومان است: err، bytesRead و buffers.


2. fs.realpath() و fs.realpath.native()


مسیر واقعی فایل یا پوشه را با حل کردن .، .. و لینک‌های نمادین بازمی‌گرداند. در صورت عدم وجود مسیر، خطای ENOENT رخ می‌دهد.


3. fs.rename()


نام فایل یا پوشه را تغییر می‌دهد. اگر مقصد وجود داشته باشد، بازنویسی می‌شود؛ اگر مقصد پوشه باشد، خطا رخ می‌دهد.


4. fs.rmdir() و fs.rm()


rmdir() پوشه را حذف می‌کند (منسوخ). rm() فایل‌ها و پوشه‌ها را با گزینه‌های recursive و force حذف می‌کند.


5. fs.stat() و fs.statfs()


اطلاعات آماری فایل (fs.Stats) یا سیستم فایل (fs.StatFs) را بازمی‌گرداند. گزینهٔ bigint می‌تواند مقادیر عددی را به‌صورت BigInt ارائه دهد.


6. fs.symlink()


یک لینک نمادین ایجاد می‌کند. در ویندوز نوع لینک می‌تواند file، dir یا junction باشد.


7. fs.truncate()


فایل را کوتاه یا بلند می‌کند تا به طول مشخص برسد. اگر کوتاه‌تر شود، با بایت‌های صفر ('\0') پر می‌شود.


8. fs.unlink()


یک فایل یا لینک نمادین را حذف می‌کند. برای حذف پوشه باید از fs.rmdir() یا fs.rm() استفاده شود.


9. fs.unwatchFile(), fs.watch(), fs.watchFile()


این متدها تغییرات فایل یا پوشه را مانیتور می‌کنند. fs.watch() کارآمدتر از fs.watchFile() است. fs.unwatchFile() مانیتورینگ را متوقف می‌کند.


10. fs.utimes()


زمان‌های دسترسی (atime) و تغییر (mtime) فایل را تغییر می‌دهد.


11. fs.write()


داده‌ها را در فایل مشخص‌شده توسط File Descriptor می‌نویسد. Callback شامل سه آرگومان است: err، bytesWritten و buffer. استفادهٔ همزمان بدون انتظار برای Callback ناامن است؛ در این موارد باید از fs.createWriteStream() استفاده شود.


نتیجه‌گیری


ماژول fs در Node.js با متدهای Callback-based ابزارهای قدرتمندی برای مدیریت پیشرفتهٔ فایل‌ها و پوشه‌ها ارائه می‌دهد. این متدها امکان خواندن و نوشتن داده‌ها، تغییر مسیرها، حذف فایل‌ها و مانیتورینگ تغییرات را فراهم می‌کنند. استفادهٔ صحیح از این متدها باعث افزایش کارایی و جلوگیری از خطاهای همزمانی در پروژه‌های بزرگ می‌شود.


1. fs.write()


رشته‌ای را در فایل مشخص‌شده توسط File Descriptor می‌نویسد.


  • fd: File Descriptor.
  • string: دادهٔ رشته‌ای.
  • position: موقعیت نوشتن در فایل.
  • encoding: نوع رمزگذاری (پیش‌فرض: utf8).

Callback شامل سه آرگومان است: err، written و string.


2. fs.writeFile()


داده‌ای را به فایل می‌نویسد و در صورت وجود فایل آن را جایگزین می‌کند.


  • file: مسیر یا File Descriptor.
  • data: رشته یا Buffer.
  • options: شامل encoding، mode و flag.

import { writeFile } from 'node:fs';
writeFile('message.txt', 'Hello Node.js', 'utf8', (err) => {
  if (err) throw err;
  console.log('File saved!');
});

امکان لغو عملیات با AbortSignal وجود دارد. برای کدهای حساس به عملکرد، استفاده از fs.createWriteStream() توصیه می‌شود.


3. fs.writev()


چندین Buffer یا TypedArray را به فایل می‌نویسد. Callback شامل سه آرگومان است: err، bytesWritten و buffers.


4. Synchronous APIs


این متدها عملیات را به‌صورت همزمان انجام می‌دهند و حلقهٔ رویداد را تا پایان عملیات مسدود می‌کنند.


  • fs.accessSync(): بررسی دسترسی به فایل.
  • fs.appendFileSync(): افزودن داده به فایل.
  • fs.chmodSync(): تغییر مجوزهای فایل.
  • fs.chownSync(): تغییر مالک فایل.
  • fs.closeSync(): بستن File Descriptor.
  • fs.copyFileSync(): کپی فایل.
  • fs.cpSync(): کپی پوشه‌ها و ساختارهای کامل.

نتیجه‌گیری


ماژول fs در Node.js ابزارهای قدرتمندی برای نوشتن داده‌ها در فایل‌ها ارائه می‌دهد. متدهای Callback برای مدیریت غیرهمزمان مناسب‌اند، در حالی که متدهای Synchronous برای اسکریپت‌های ساده یا محیط‌هایی که نیاز به کنترل فوری دارند کاربرد دارند. انتخاب صحیح بین این دو رویکرد باعث افزایش کارایی و جلوگیری از خطاهای همزمانی در پروژه‌های بزرگ می‌شود.


1. fs.existsSync()


بررسی می‌کند که آیا مسیر مشخص وجود دارد یا خیر. مقدار بازگشتی یک بولین است. برخلاف نسخهٔ غیرهمزمان، این متد منسوخ نشده است.


2. fs.fchmodSync() و fs.fchownSync()


مجوزها و مالکیت فایل را با استفاده از File Descriptor تغییر می‌دهند.


3. fs.fdatasyncSync() و fs.fsyncSync()


داده‌های در صف را به دیسک همگام‌سازی می‌کنند. fdatasyncSync() فقط داده‌ها را همگام می‌کند، در حالی که fsyncSync() داده‌ها و متادیتا را همگام می‌کند.


4. fs.fstatSync()


اطلاعات آماری فایل را بر اساس File Descriptor بازمی‌گرداند. گزینهٔ bigint می‌تواند مقادیر عددی را به‌صورت BigInt ارائه دهد.


5. fs.ftruncateSync()


فایل را به طول مشخص کوتاه یا بلند می‌کند. اگر کوتاه‌تر شود، با بایت‌های صفر ('\0') پر می‌شود.


6. fs.futimesSync()


زمان‌های دسترسی (atime) و تغییر (mtime) فایل را بر اساس File Descriptor تغییر می‌دهد.


7. fs.globSync()


فایل‌ها را بر اساس الگوهای glob جستجو می‌کند و مسیرهای مطابق الگو را بازمی‌گرداند.


8. fs.lchmodSync(), fs.lchownSync(), fs.lutimesSync()


  • lchmodSync(): تغییر مجوزهای لینک نمادین (منسوخ، فقط در macOS).
  • lchownSync(): تغییر مالک لینک نمادین.
  • lutimesSync(): تغییر زمان‌های لینک نمادین بدون دنبال‌کردن مقصد.

9. fs.linkSync()


ایجاد یک لینک سخت از مسیر موجود به مسیر جدید.


10. fs.lstatSync()


اطلاعات آماری لینک نمادین را بازمی‌گرداند، نه فایل مقصد آن.


11. fs.mkdirSync(), fs.mkdtempSync(), fs.mkdtempDisposableSync()


ایجاد پوشه‌ها به‌صورت همزمان. mkdtempSync() پوشهٔ موقت یکتا ایجاد می‌کند و mkdtempDisposableSync() شیء disposable بازمی‌گرداند که امکان حذف پوشه را دارد.


12. fs.opendirSync() و fs.openSync()


پوشه یا فایل را باز می‌کنند و یک fs.Dir یا File Descriptor بازمی‌گردانند.


13. fs.readdirSync()


محتوای پوشه را بازمی‌گرداند. گزینهٔ withFileTypes می‌تواند اشیاء Dirent بازگرداند.


14. fs.readFileSync()


کل محتوای فایل را به‌صورت همزمان می‌خواند. اگر encoding مشخص شود، داده به‌صورت رشته بازمی‌گردد؛ در غیر این صورت به‌صورت Buffer.


نتیجه‌گیری


ماژول fs در Node.js با متدهای Synchronous ابزارهای قدرتمندی برای مدیریت فایل‌ها و پوشه‌ها ارائه می‌دهد. این متدها برای اسکریپت‌های ساده یا محیط‌هایی که نیاز به کنترل فوری دارند مناسب‌اند، اما در برنامه‌های بزرگ می‌توانند باعث کاهش کارایی شوند. استفادهٔ صحیح از این متدها باعث افزایش قابلیت اطمینان و سادگی در پروژه‌های کوچک و متوسط می‌شود.


1. fs.readlinkSync()


مسیر مقصد یک لینک نمادین را بازمی‌گرداند. اگر encoding برابر با buffer باشد، خروجی به‌صورت Buffer خواهد بود.


2. fs.readSync() و fs.readvSync()


داده‌ها را از فایل مشخص‌شده توسط File Descriptor می‌خوانند. readSync() داده را در یک Buffer می‌نویسد، در حالی که readvSync() داده را در چندین Buffer ذخیره می‌کند.


3. fs.realpathSync() و fs.realpathSync.native()


مسیر واقعی فایل یا پوشه را با حل کردن .، .. و لینک‌های نمادین بازمی‌گرداند.


4. fs.renameSync()


نام فایل یا پوشه را تغییر می‌دهد. اگر مقصد وجود داشته باشد، بازنویسی می‌شود.


5. fs.rmdirSync() و fs.rmSync()


rmdirSync() پوشه را حذف می‌کند (منسوخ). rmSync() فایل‌ها و پوشه‌ها را با گزینه‌های recursive و force حذف می‌کند.


6. fs.statSync() و fs.statfsSync()


اطلاعات آماری فایل (fs.Stats) یا سیستم فایل (fs.StatFs) را بازمی‌گرداند.


7. fs.symlinkSync()


یک لینک نمادین ایجاد می‌کند. در ویندوز نوع لینک می‌تواند file، dir یا junction باشد.


8. fs.truncateSync()


فایل را کوتاه یا بلند می‌کند تا به طول مشخص برسد.


9. fs.unlinkSync()


یک فایل یا لینک نمادین را حذف می‌کند.


10. fs.utimesSync()


زمان‌های دسترسی (atime) و تغییر (mtime) فایل را تغییر می‌دهد.


11. fs.writeFileSync(), fs.writeSync(), fs.writevSync()


داده‌ها را به فایل می‌نویسند. writeFileSync() کل داده را ذخیره می‌کند، writeSync() داده را در یک Buffer یا رشته می‌نویسد، و writevSync() چندین Buffer را به فایل می‌نویسد.


12. کلاس‌های مشترک


  • fs.Dir: نمایندهٔ جریان پوشه.
  • fs.Dirent: نمایندهٔ یک ورودی پوشه (فایل یا زیرپوشه).
  • fs.FSWatcher: مانیتور تغییرات فایل‌ها و پوشه‌ها.
  • fs.StatWatcher: مانیتور تغییرات آماری فایل.
  • fs.ReadStream: جریان خواندن فایل.
  • fs.Stats: اطلاعات آماری فایل.
  • fs.StatFs: اطلاعات آماری سیستم فایل.
  • fs.Utf8Stream: جریان نوشتن بهینه‌شده برای UTF-8.

نتیجه‌گیری


ماژول fs در Node.js با متدهای Synchronous پیشرفته ابزارهای قدرتمندی برای مدیریت فایل‌ها و پوشه‌ها ارائه می‌دهد. این متدها برای اسکریپت‌های ساده یا محیط‌هایی که نیاز به کنترل فوری دارند مناسب‌اند، اما در برنامه‌های بزرگ می‌توانند باعث کاهش کارایی شوند. استفادهٔ صحیح از این متدها باعث افزایش قابلیت اطمینان و سادگی در پروژه‌های کوچک و متوسط می‌شود.


نوشته و پژوهش شده توسط دکتر شاهین صیامی