کتابخانه‌ی استاندارد · سیستم و ابزار

مسیر fs/path

کار با مسیر پرونده‌ها: پیوند زدن، جدا کردن نام و پسوند، مسیر مطلق و نسبی و بررسی امنیت.

واردسازی سیستم پرونده.مسیر

بسته‌ی مسیر مسیرها را از هم باز می‌کند و کنار هم می‌گذارد: پیوستن، جدا کردن، ساده کردن، مطلق یا نسبی کردن، و بررسی این‌که مسیری که از کاربر آمده درون یک پوشه می‌ماند. هر تابع نام دیگری برای همان تابع در بسته‌ی مسیر پرونده است (نام پرونده به‌جای نام پایه، و نام پوشه و پوشه والد به‌جای پوشه)، پس یکی از دو بسته را انتخاب کنید و در سراسر برنامه همان را به کار ببرید. یک نام معنای دیگری دارد: مسیر پرونده.نام پایه پسوند را نگه می‌دارد ولی مسیر.نام پایه آن را برمی‌دارد. مسیر کنار بسته‌های پرونده و پوشه خواناتر است.

مسیرها را با چسباندن رشته‌ها نسازید؛ پیوند جداکننده را خودش می‌گذارد. جداکننده همیشه / است، در ویندوز هم: هر تابع اول \ را به / تبدیل می‌کند و ویندوز / را در مسیر می‌پذیرد. وقتی مسیری از کاربر می‌گیرید، پیش از باز کردن با مسیر امن است بررسی کنید که کسی با ../.. از پوشه‌ی مجاز بیرون نزند.

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

اشتباه‌های رایج:

  • انتظار مرتب‌سازی از پیوند. فقط جداکننده را می‌افزاید یا یکی می‌کند، پس پیوند("a/b"، "../c") برابر a/b/../c است؛ نتیجه را از پاک سازی بگذرانید. بخش دوم مطلق هم جای بخش اول را نمی‌گیرد، برخلاف os.path.join در پایتون.
  • کل پسوند دانستن پسوند. فقط آخرین پسوند است: .gz برای backup.tar.gz، و برای پرونده‌ی نقطه‌دار مثل .bashrc خالی.
  • مقایسه‌ی متنی مسیرها بدون پاک سازی. docs/./cv.pdf و docs/cv.pdf یک پرونده‌اند. مقایسه‌ها به بزرگی و کوچکی حرف هم حساس‌اند، که در ویندوز و دیسک‌های پیش‌فرض مک نادرست است.

فرستادن پرونده‌ای که کاربر خواسته

یک بخش دانلود نامی مثل 2026/report.pdf را از درخواست می‌گیرد و باید آن را به پرونده‌ای درون یک پوشه‌ی مشخص تبدیل کند. مسیر امن است اول مسیر پیوندخورده را ساده می‌کند و بعد بررسی می‌کند که هنوز با آن پوشه شروع شود؛ پس a/../b.txt پذیرفته می‌شود ولی ../secret.txt و a/../../etc/passwd رد می‌شوند. نام خالی هم رد می‌شود.

fs-path-guide-safe.salam
واردسازی سیستم پرونده.مسیر

تابع پیدا کن(پوشه اصلی: رشته، خواسته: رشته): رشته:
    اگر وارونه مسیر.مسیر امن است(پوشه اصلی، خواسته): برگشت "" پایان
    برگشت مسیر.پاک سازی(مسیر.پیوند(پوشه اصلی، خواسته))
پایان

تابع ریشه:
    پوشه بارگذاری := "/srv/uploads"
    هر نام در ["avatar.png"، "2026/report.pdf"، "a/../b.txt"، "../secret.txt"، "a/../../etc/passwd"، "/etc/passwd"، ""]:
        کامل := پیدا کن(پوشه بارگذاری، نام)
        اگر کامل.طول() برابر ۰:
            سرچاپ "رد شد"، "[" + نام + "]"
        وگرنه:
            سرچاپ "فرستاده شد"، کامل
        پایان
    پایان
پایان
خروجیفرستاده شد /srv/uploads/avatar.png فرستاده شد /srv/uploads/2026/report.pdf فرستاده شد /srv/uploads/b.txt رد شد [../secret.txt] رد شد [a/../../etc/passwd] فرستاده شد /srv/uploads/etc/passwd رد شد []

به خط /etc/passwd دقت کنید: پیوند نمی‌گذارد بخش دوم مطلق جای بخش اول را بگیرد، پس نتیجه درون همان پوشه می‌افتد و امن است. این بررسی فقط روی متن انجام می‌شود و پیوندهای نمادین را دنبال نمی‌کند؛ پس در پوشه‌ای که از آن پرونده می‌فرستید پیوندی به بیرون نگذارید.

نگاشت یک درخت پوشه به درختی دیگر

یک سازنده‌ی سایت ایستا content/blog/hello.md را می‌خواند و public/blog/hello.html را می‌نویسد. مسیر نسبی بخشی را که زیر پوشه‌ی منبع است می‌دهد، نام پوشه و نام بدون پسوند آن را تکه می‌کنند و پیوند و پاک سازی مسیر تازه را می‌سازند. نام بدون پسوند فقط پسوند آخر را برمی‌دارد، پس salam.v2.md بخش .v2 را نگه می‌دارد.

fs-path-guide-output.salam
واردسازی سیستم پرونده.مسیر

تابع مسیر خروجی(ریشه منبع: رشته، ریشه خروجی: رشته، پرونده: رشته): رشته:
    نسبی := مسیر.مسیر نسبی(ریشه منبع، پرونده)
    پوشه مقصد := مسیر.پیوند(ریشه خروجی، مسیر.نام پوشه(نسبی))
    صفحه‌ی خروجی := مسیر.نام بدون پسوند(نسبی).پیوست(".html")
    برگشت مسیر.پاک سازی(مسیر.پیوند(پوشه مقصد، صفحه‌ی خروجی))
پایان

تابع ریشه:
    منبع := "/site/content"
    خروجی := "/site/public"
    هر پرونده در ["/site/content/index.md"، "/site/content/blog/hello.md"، "/site/content/blog/2026/salam.v2.md"]:
        سرچاپ مسیر.مسیر نسبی(منبع، پرونده)، "->"، مسیر خروجی(منبع، خروجی، پرونده)
    پایان
پایان
خروجیindex.md -> /site/public/index.html blog/hello.md -> /site/public/blog/hello.html blog/2026/salam.v2.md -> /site/public/blog/2026/salam.v2.html

برای پرونده‌ای که مستقیم در پوشه‌ی منبع است، نام پوشه مقدار . را برمی‌گرداند و پاک سازی پایانی آن /. را که پیوند جا گذاشته حذف می‌کند. نمونه مسیرهای مطلق به کار می‌برد، چون مسیر نسبی مسیرهای نسبی را اول نسبت به پوشه‌ی جاری مطلق می‌کند.

ساختن نام تازه کنار یک پرونده

برای گذاشتن نسخه‌ی پشتیبان، تصویر کوچک یا رونوشت تبدیل‌شده کنار پرونده‌ی اصلی، پوشه را نگه دارید و فقط نام را عوض کنید. این‌جا نام بدون پسوند و پسوند از plan.md نام plan.bak.md را می‌سازند و بسته‌های پوشه و ورودی خروجی کار روی دیسک را انجام می‌دهند.

fs-path-guide-backup.salam
واردسازی سیستم پرونده.مسیر
واردسازی سیستم پرونده.پوشه
واردسازی ورودی خروجی

تابع نام پشتیبان(پ: رشته): رشته:
    نام تازه := مسیر.نام بدون پسوند(پ).پیوست(".bak").پیوست(مسیر.پسوند(پ))
    برگشت مسیر.پیوند(مسیر.نام پوشه(پ)، نام تازه)
پایان

تابع ریشه:
    پوشه.ساخت پوشه ها("notes/2026")
    هر پ در ["notes/todo.txt"، "notes/2026/plan.md"]:
        ورودی خروجی.نوشتن پرونده(پ، "پیش‌نویس ".پیوست(مسیر.نام پرونده(پ)))
        پشتیبان := نام پشتیبان(پ)
        ورودی خروجی.نوشتن پرونده(پشتیبان، ورودی خروجی.خواندن پرونده(پ))
        سرچاپ پ، "ذخیره شد در"، پشتیبان
    پایان
    سرچاپ ورودی خروجی.خواندن پرونده("notes/2026/plan.bak.md")
پایان
خروجیnotes/todo.txt ذخیره شد در notes/todo.bak.txt notes/2026/plan.md ذخیره شد در notes/2026/plan.bak.md پیش‌نویس plan.md

کدام تابع برای کدام کار

نام چند تابع این بسته به هم نزدیک است. نام پرونده پسوند را نگه می‌دارد ولی نام پایه و نام بدون پسوند هر دو آن را برمی‌دارند. نرمال سازی فقط \ را به / تبدیل می‌کند و پاک سازی است که . و .. را حل می‌کند.

می‌خواهیدتابعبرای /home/sara/docs/cv.pdf
پوشهنام پوشه یا پوشه والد/home/sara/docs
نام با پسوندنام پروندهcv.pdf
نام بدون پسوندنام بدون پسوند یا نام پایهcv
پسوندپسوند.pdf
پوشه و نام با همتقسیمفیلدهای dir و base
حذف .، .. و خط‌های مورب تکراریپاک سازیبی‌تغییر
مسیر از یک پوشه به پوشه‌ی دیگرمسیر نسبیdocs/cv.pdf از /home/sara
بررسی مسیری که کاربر دادهمسیر امن استtrue درون پوشه‌ی پایه

اعتبارسنجی مسیر فقط رشته‌ی خالی را رد می‌کند. بررسی امنیتی نیست؛ برای آن مسیر امن است را به کار ببرید.

گونه‌ها

اجزای مسیر PathParts

ساختار اجزای مسیر
دو بخش یک مسیر.
نامانگلیسیگونهتوضیح
پوشهdirرشته = ""بخش پوشه.
نام پروندهbaseرشته = ""نام پرونده.
fs-path-Join.salam
واردسازی سیستم پرونده.مسیر

تابع ریشه:
    پ := مسیر.پیوند("/home/sara"، "docs/cv.pdf")
    سرچاپ پ
    ت := مسیر.تقسیم(پ)
    سرچاپ ت.پوشه، ت.نام پرونده
    سرچاپ مسیر.نام پوشه(پ)، مسیر.پوشه والد(پ)، مسیر.نام پرونده(پ)، مسیر.نام پایه(پ)
    سرچاپ مسیر.پسوند(پ)، مسیر.نام بدون پسوند(پ)
    سرچاپ مسیر.نرمال سازی("/a/./b/../c//d")، مسیر.پاک سازی("a/b/../../c")
    سرچاپ مسیر.مطلق است(پ)، مسیر.مطلق است("docs")، مسیر.مطلق است(مسیر.مسیر مطلق("docs"))
    سرچاپ مسیر.مسیر نسبی("/home/sara"، "/home/sara/docs/cv.pdf")
    سرچاپ مسیر.مسیر امن است("/srv/files"، "a/b.txt")، مسیر.مسیر امن است("/srv/files"، "../../etc/passwd")
    سرچاپ مسیر.اعتبارسنجی مسیر("docs/cv.pdf")، مسیر.اعتبارسنجی مسیر("")
پایان
خروجی/home/sara/docs/cv.pdf /home/sara/docs cv.pdf /home/sara/docs /home/sara/docs cv.pdf cv .pdf cv /a/./b/../c//d c true false true docs/cv.pdf true false true false

تابع‌ها

پیوند Join

تابع پیوند(a: رشته، b: رشته): رشته
دو بخش مسیر را با یک / میانشان می‌پیوندد. بخش خالی بخش دیگر را می‌دهد؛ . و .. می‌مانند، پس وقتی مهم است نتیجه را پاک سازی کنید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

تقسیم Split

تابع تقسیم(p: رشته): اجزای مسیر
مسیر را به پوشه (نام پوشه) و نام پرونده (نام پرونده) جدا می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

نرمال سازی Normalize

تابع نرمال سازی(p: رشته): رشته
جداکننده‌های \ ویندوز را به / تبدیل می‌کند؛ کار دیگری نمی‌کند. برای ساده کردن .. و .، پاک سازی را ببینید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

پاک سازی Clean

تابع پاک سازی(p: رشته): رشته
مسیر را ساده می‌کند: . و .. را حل می‌کند، جداکننده‌های تکراری و پایانی را برمی‌دارد و برای مسیر خالی . می‌دهد. .. بالاتر از ریشه‌ی مسیر مطلق کنار گذاشته می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

مطلق است IsAbs

تابع مطلق است(p: رشته): منطقی
اگر مسیر با / یا با حرف درایوی مثل C: شروع شود، درست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

مسیر مطلق Abs

تابع مسیر مطلق(p: رشته): رشته
مسیر را نسبت به پوشه‌ی جاری مطلق و ساده می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

مسیر نسبی Rel

تابع مسیر نسبی(base: رشته، target: رشته): رشته
مسیر target نسبت به base، با گام‌های .. وقتی بیرون از آن است؛ اگر یکی باشند .. هر دو اول مطلق می‌شوند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

پوشه والد Parent

تابع پوشه والد(p: رشته): رشته
پوشه‌ی والد؛ همان نام پوشه.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

نام پوشه Dirname

تابع نام پوشه(p: رشته): رشته
بخش پوشه‌ی مسیر: اگر نباشد . و برای پرونده‌ای در ریشه /. / پایانی نادیده گرفته می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

نام پرونده Filename

تابع نام پرونده(p: رشته): رشته
نام پرونده همراه با پسوند، آخرین بخش مسیر.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

نام پایه Basename

تابع نام پایه(p: رشته): رشته
نام پرونده بدون پوشه و بدون پسوند؛ مثل نام بدون پسوند. برای نام همراه پسوند، نام پرونده را به کار ببرید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

پسوند Ext

تابع پسوند(p: رشته): رشته
آخرین پسوند با نقطه‌اش، مثل .gz؛ اگر نباشد یا نام با تنها نقطه‌اش شروع شود (.bashrc) خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

نام بدون پسوند Stem

تابع نام بدون پسوند(p: رشته): رشته
نام پرونده بدون آخرین پسوند: backup.tar برای backup.tar.gz.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

مسیر امن است IsSafe

تابع مسیر امن است(base: رشته، p: رشته): منطقی
اگر p پس از پیوستن به base و ساده شدن خود base باشد یا درون آن، درست برمی‌گرداند. p خالی رد می‌شود. روی متن کار می‌کند و پیوندهای نمادین را دنبال نمی‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam

اعتبارسنجی مسیر Validate

تابع اعتبارسنجی مسیر(p: رشته): منطقی
اگر مسیر خالی نباشد، درست برمی‌گرداند؛ بررسی دیگری انجام نمی‌دهد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: fs-path-Join.salam