پرونده fs/file
خواندن و نوشتن پرونده، اطلاعات پرونده، رونوشت و جابهجایی، و چکیدهی MD5 و SHA.
واردسازی سیستم پرونده.پرونده
بستهی پرونده کاملترین ابزار کار با یک پرونده است: خواندن کامل یا خطبهخط، نوشتن، افزودن، جایگزینی امن، رونوشت، جابهجایی و حذف، دانستن اندازه و زمانها و مجوزها، چکیده گرفتن و حدس نوع مایم. تابعهای رونوشت، جابهجایی، حذف و نوشتن اتمی شکست را در بستهی خطا ثبت میکنند؛ خواندنها و نوشتنهای ساده نه، پس نتیجهشان را بررسی کنید. برای پوشهها بستهی پوشه، برای مسیرها مسیر و برای خواندن تکهتکهی یک پروندهی بزرگ تابعهای دستگیرهی بستهی ورودی خروجی را ببینید.
نوشتنها تعداد بایتهای نوشتهشده یا -۱ را برمیگردانند. خواندنها وقتی پرونده باز نشود متن خالی میدهند، درست مثل پروندهی خالی؛ وقتی این فرق مهم است وجود دارد را بپرسید.
اشتباههای رایج:
- دودوییامن دانستن این بسته. هر خواندن و نوشتنی از یک
رشتهمیگذرد که در نخستین بایت صفر تمام میشود، پسخواندن همه،خواندن بایتها،نوشتن بایتهاو تابعهای چکیده پروندهی دودویی را کوتاه میکنند. برای تصویر، بایگانی و هر دادهی دودویی دیگرخواندن پرونده دودوییونوشتن پرونده دودوییاز بستهی بایگانی را به کار ببرید که اشارهگر و طول را جابهجا میکنند، و برای چکیده شکلهای اشارهگری بستهی رمزنگاری مثلشا۲۵۶ بایترا. - انتظار اینکه
جابجاییاز دیسکی به دیسک دیگر برود. این تابع تغییر نام است و میان دو سیستم پرونده شکست میخورد؛پوشه.جابجاییبه رونوشت برمیگردد، یا خودتان رونوشت بگیرید و حذف کنید. - گمان اینکه
نوشتن اتمیمجوزهای پروندهی قدیمی را نگه میدارد. پروندهی تازهای مینویسد که مجوزهای پیشفرض را میگیرد؛ پروندهای که به0o600تنگ کرده بودید دوباره خواندنی میشود، مگر پس از هر ذخیرهتغییر مجوزرا صدا بزنید. - به معنای «پرونده است» گرفتن
وجود دارد. برای پوشه هم درست است؛ آن را باپوشه.پوشه استهمراه کنید.
خواندن پروندهی تنظیمات خط به خط
خواندن خطها پرونده را در شکستهای خط جدا میکند و \r انتهای خط را هم برمیدارد، پس پروندهای که در ویندوز ذخیره شده همانطور خوانده میشود که پروندهی لینوکسی. با این کار پروندههای سادهی کلید = مقدار آسان میشوند: هر خط را بپیرایید، خطهای خالی و توضیحها را رد کنید و در اولین = جدا کنید.
واردسازی سیستم پرونده.پرونده
واردسازی رشته
تابع ریشه:
پرونده.نوشتن متن("برنامه.conf"، "# تنظیمات فروشگاه\nname = فروشگاه سر کوچه\n\nport = 8080\ncurrency = IRR\n")
تنظیمات := نگاشت {} برگردان نگاشت<رشته، رشته>
هر سطر در پرونده.خواندن خطها("برنامه.conf"):
ت := سطر.پیراست()
اگر ت.طول() == ۰ یا رشته.شروع با(ت، "#"): گذر پایان
جای مساوی := رشته.اندیس(ت، "=")
اگر جای مساوی < ۰: گذر پایان
تنظیمات.درج(ت.زیررشته(۰، جای مساوی).پیراست()، ت.زیررشته(جای مساوی + ۱، ت.طول() - جای مساوی - ۱).پیراست())
پایان
سرچاپ تنظیمات.اندازه()، "تنظیم"
سرچاپ "نام:"، تنظیمات.بگیر("name")
سرچاپ "درگاه:"، تنظیمات.بگیر("port")
پرونده.حذف("برنامه.conf")
پایانبرای قالبی با بخشبندی، نقلقول یا ساختار تو در تو، یک تجزیهگر واقعی مثل تامل، جیسون یا پرونده محیط را به کار ببرید.
افزودن به پروندهی گزارش
افزودن پرونده را باز میکند، متن را به انتهایش اضافه میکند و دوباره میبندد، و در اولین فراخوانی پرونده را میسازد. هر فراخوانی یک باز و بسته کردن جداست که برای یک خط گاهبهگاه خوب است. برای گزارشی پرکار، پرونده را یک بار با بازکردن(پ، "ab") باز کنید، با ورودی خروجی.نوشتن بنویسید و در پایان بستن را صدا بزنید.
واردسازی سیستم پرونده.پرونده
تابع ثبت(سطر: رشته):
پرونده.افزودن("برنامه.log"، سطر.پیوست("\n"))
پایان
تابع ریشه:
ثبت("شروع شد")
ثبت("۳ سفارش بارگذاری شد")
ثبت("صورتحساب ۱۰۴۲ فرستاده شد")
ثبت("متوقف شد")
سطرها := پرونده.خواندن خطها("برنامه.log")
سرچاپ "گزارش"، سطرها.طول()، "خط و"، پرونده.اندازه("برنامه.log")، "بایت دارد"
سرچاپ "دو خط آخر:"
ناپایا ی := سطرها.طول() - ۲
تا ی < سطرها.طول():
سرچاپ " "، سطرها.بگیر(ی)
ی += ۱
پایان
پرونده.حذف("برنامه.log")
پایانبررسی سالم رسیدن پرونده
صفحههای دانلود اغلب کنار هر پرونده چکیدهی SHA-256 آن را منتشر میکنند. چکیدهی نسخهی خودتان را با هش شا۲۵۶ حساب کنید و دو مقدار را مقایسه کنید: تغییر حتی یک بایت چکیدهی کاملاً متفاوتی میدهد. هش امدی۵ و هش شا۱ برای فهمیدن تغییرهای ناخواسته، مثلاً به عنوان کلید حافظهی پنهان، خوباند؛ اما هر کسی میتواند عمداً دو پروندهی متفاوت با MD5 یا SHA-1 یکسان بسازد، پس در برابر مهاجم به آنها اعتماد نکنید.
واردسازی سیستم پرونده.پرونده
تابع سالم است(پ: رشته): منطقی:
انتظار := پرونده.خواندن متن(پ.پیوست(".sha256")).پیراست()
برگشت پرونده.هش شا۲۵۶(پ) == انتظار
پایان
تابع ریشه:
پرونده.نوشتن بایتها("انتشار.tar"، "pretend this is a release archive")
پرونده.نوشتن متن("انتشار.tar.sha256"، پرونده.هش شا۲۵۶("انتشار.tar").پیوست("\n"))
سرچاپ "سالم:"، سالم است("انتشار.tar")
پرونده.افزودن("انتشار.tar"، "!")
سرچاپ "پس از تغییر:"، سالم است("انتشار.tar")
پرونده.حذف("انتشار.tar")
پرونده.حذف("انتشار.tar.sha256")
پایانتابعهای چکیده اول پرونده را در یک رشته میخوانند و رشتهی سلام در اولین بایت صفر تمام میشود. برای پروندههای متنی این مهم نیست. اما پروندهی دودوییای که بایت صفر دارد، که بیشتر بایگانیها و تصویرها دارند، فقط تا همان بایت چکیده میشود؛ چنین پروندههایی را با sha256sum سیستم یا با تابعهای بافری رمزنگاری مثل شا۲۵۶ بایت بررسی کنید. همین محدودیت برای خواندن همه، خواندن متن، خواندن بایتها و نوشتن بایتها هم هست.
ذخیره بدون از دست دادن نسخهی قبلی
نوشتن اتمی محتوای تازه را در نام.tmp کنار پروندهی مقصد مینویسد و بعد در یک گام آن را جای مقصد میگذارد. برنامهای که در میانهی کار از کار بیفتد یا پروندهی قدیمی را باقی میگذارد یا پروندهی تازه را، هرگز نیمی از هر کدام. داده را پیش از آن روی دیسک نمینشاند، پس پس از قطع برق پروندهای که لحظهای پیش ذخیره شده روی برخی سیستمهای پرونده هنوز ممکن است از دست برود، و دو برنامه که همزمان یک پرونده را ذخیره کنند نام .tmp یکسانی دارند. رونوشت گرفتن از پروندهی قدیمی در .bak پیش از آن، یک نسخهی قبلی را هم نگه میدارد. اگر پوشه وجود نداشته باشد، نوشتن اتمی مقدار -1 برمیگرداند و پیامش را در خطا میگذارد.
واردسازی سیستم پرونده.پرونده
واردسازی سیستم عامل.خطا
تابع ذخیره(پ: رشته، داده: رشته): منطقی:
اگر پرونده.وجود دارد(پ): پرونده.کپی(پ، پ.پیوست(".bak")) پایان
اگر پرونده.نوشتن اتمی(پ، داده) != ۰:
سرچاپ "ذخیره نشد:"، خطا.پیام آخرین خطا()
برگشت نادرست
پایان
برگشت درست
پایان
تابع ریشه:
ذخیره("نمایه.json"، "{\"name\": \"سارا\"}")
ذخیره("نمایه.json"، "{\"name\": \"سارا\", \"city\": \"تبریز\"}")
سرچاپ "نسخهی فعلی:"، پرونده.خواندن متن("نمایه.json")
سرچاپ "پشتیبان:"، پرونده.خواندن متن("نمایه.json.bak")
سرچاپ "پروندهی موقت ماند:"، پرونده.وجود دارد("نمایه.json.tmp")
ذخیره("پوشه-ناموجود/نمایه.json"، "{}")
پرونده.حذف("نمایه.json")
پرونده.حذف("نمایه.json.bak")
پایانفرستادن پرونده با نوع درست
سرور وب باید همراه هر پرونده یک Content-Type بفرستد. نوع مایم آن را فقط از روی پسوند و بدون توجه به کوچکی و بزرگی حروف انتخاب میکند و نوعهای رایج وب، تصویر، صدا، ویدیو و بایگانی را میشناسد؛ هر چیز دیگری application/octet-stream است که مرورگر به جای نمایش، دانلودش میکند. پسوند نقطه و شکل اصلی حروف را نگه میدارد و برای نامی که پسوند ندارد خالی است.
واردسازی سیستم پرونده.پرونده
تابع ریشه:
هر نام در ["index.html"، "app.js"، "logo.SVG"، "photo.jpeg"، "داده.json"، "یادداشت"، "backup.7z"]:
پسوند := پرونده.پسوند(نام)
اگر پسوند == "": سرچاپ نام، "(بدون پسوند)"، پرونده.نوع مایم(نام)
وگرنه: سرچاپ نام، پسوند، پرونده.نوع مایم(نام)
پایان
پایان
پایانسرور HTTP معمولاً بهتر است مایم را به کار ببرد: رده مایم در آن بسته به نوعهای متنی ; charset=utf-8 اضافه میکند و قلمهای وب را هم میشناسد، و خود بسته سرآیند Content-Type و بدنههای چندبخشی را هم تجزیه میکند.
کدام تابع برای کدام کار
| کار | تابع |
|---|---|
| خواندن یکجای پروندهی متنی کوچک | خواندن متن، یا خواندن خطها برای وکتوری از خطها |
| خواندن فقط ابتدای پرونده | خواندن بایتها |
| جایگزین کردن محتوای پرونده | نوشتن متن، یا نوشتن اتمی وقتی پرونده مهم است |
| افزودن به انتهای پرونده | افزودن |
| کار تکهبهتکه با پروندهی بزرگ | بازکردن، بعد تابعهای ورودی خروجی، بعد بستن |
| اندازه، زمانها و مجوزها با یک فراخوانی | وضعیت |
| رونوشت، جابهجایی یا حذف | کپی، جابجایی (یا تغییر نام)، حذف |
| بررسی یک دانلود | هش شا۲۵۶ |
| نوع محتوا برای پاسخ وب | نوع مایم |
گونهها
اطلاعات پرونده FileInfo
ساختار اطلاعات پرونده| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| اندازه | size | صحیح۶۴ = 0 | اندازه بر حسب بایت. |
| زمان تغییر | mod_time | صحیح۶۴ = 0 | زمان آخرین تغییر. |
| زمان دسترسی | accessed_time | صحیح۶۴ = 0 | زمان آخرین دسترسی. |
| زمان ایجاد | created_time | صحیح۶۴ = 0 | زمان ایجاد. |
| مجوزها | permissions | صحیح = 0 | مجوزها، با رقمهای هشتهشتی مثل 644. |
| وجود دارد | exists | منطقی = نادرست | اگر مسیر وجود داشته باشد (پوشه هم حساب است) درست است؛ اگر نباشد بقیهی فیلدها ۰اند. |
واردسازی سیستم پرونده.پرونده
تابع ریشه:
پرونده.نوشتن متن("عکس.png"، "PNG")
و۱ := پرونده.وضعیت("عکس.png")
سرچاپ و۱.وجود دارد، و۱.اندازه، و۱.زمان تغییر > ۰، و۱.مجوزها > ۰
سرچاپ پرونده.اندازه("عکس.png")، پرونده.وجود دارد("عکس.png")
سرچاپ پرونده.زمان تغییر("عکس.png") > ۰، پرونده.زمان دسترسی("عکس.png") > ۰، پرونده.زمان ایجاد("عکس.png") >= ۰
پرونده.تغییر مجوز("عکس.png"، 0o600)
سرچاپ پرونده.مجوزها("عکس.png")
سرچاپ پرونده.پسوند("عکس.png")، پرونده.نوع مایم("عکس.png")، پرونده.نوع مایم("نامه.pdf")
سرچاپ پرونده.وضعیت("نیست.txt").وجود دارد
پایانتابعها
بازکردن Open
تابع بازکردن(path: رشته، mode: رشته): پرونده*واردسازی سیستم پرونده.پرونده
تابع ریشه:
پرونده.نوشتن متن("شعر.txt"، "بنی آدم اعضای یکدیگرند\n")
پرونده.افزودن("شعر.txt"، "که در آفرینش ز یک گوهرند\n")
چاپ پرونده.خواندن متن("شعر.txt")
سرچاپ پرونده.خواندن همه("شعر.txt") == پرونده.خواندن متن("شعر.txt")
خطها := پرونده.خواندن خطها("شعر.txt")
سرچاپ خطها.طول()، خطها.بگیر(۱)
پرونده.نوشتن بایتها("داده.bin"، "ABCDEF")
سرچاپ پرونده.خواندن بایتها("داده.bin"، ۳)
پرونده.نوشتن اتمی("تنظیمات.txt"، "زبان=فارسی")
سرچاپ پرونده.خواندن متن("تنظیمات.txt")
پ := پرونده.بازکردن("شعر.txt"، "rb")
سرچاپ پ.خواندن خط()
پرونده.بستن(پ)
پایانبستن Close
تابع بستن(f: پرونده*)نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
خواندن متن ReadText
تابع خواندن متن(path: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
خواندن همه ReadAll
تابع خواندن همه(path: رشته): رشتهخواندن متن. نتیجه یک رشته است، پس پروندهی دودویی در نخستین بایت صفرش بریده میشود.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
خواندن بایتها ReadBytes
تابع خواندن بایتها(path: رشته، n: صحیح): رشتهn بایت اول پرونده را میخواند، مثلاً سرآیندی برای شناختن قالبش؛ در بایت صفر کوتاه میشود.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
خواندن خطها ReadLines
تابع خواندن خطها(path: رشته): وکتور<رشته>\r پایانی.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
نوشتن متن WriteText
تابع نوشتن متن(path: رشته، data: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
نوشتن بایتها WriteBytes
تابع نوشتن بایتها(path: رشته، data: رشته): صحیحنوشتن متن است. داده یک رشته است، پس در نخستین بایت صفر تمام میشود و برای محتوای دودویی امن نیست.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
افزودن Append
تابع افزودن(path: رشته، data: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
نوشتن اتمی AtomicWrite
تابع نوشتن اتمی(path: رشته، data: رشته): صحیحpath.tmp را مینویسد و آن را روی پرونده تغییر نام میدهد، پس برنامهی قطعشده یا نسخهی کامل تازه را باقی میگذارد یا قدیمی را، هرگز پروندهی نیمهنوشته. ۰ یا -۱ (همراه با ثبت در خطا) برمیگرداند. پروندهی تازه مجوزهای پیشفرض را میگیرد و داده پیش از آن روی دیسک نشانده نمیشود.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-ReadText.salam
اندازه Size
تابع اندازه(p: رشته): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
زمان تغییر ModTime
تابع زمان تغییر(p: رشته): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
زمان دسترسی AccessedTime
تابع زمان دسترسی(p: رشته): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
زمان ایجاد CreatedTime
تابع زمان ایجاد(p: رشته): صحیح۶۴نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
مجوزها Permissions
تابع مجوزها(p: رشته): صحیحنمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
تغییر مجوز Chmod
تابع تغییر مجوز(p: رشته، mode: صحیح): صحیح0o600.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
پسوند Extension
تابع پسوند(p: رشته): رشته.JPG؛ اگر نباشد خالی.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
نوع مایم MimeType
تابع نوع مایم(p: رشته): رشتهapplication/octet-stream. پرونده باز نمیشود.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
وضعیت Stat
تابع وضعیت(p: رشته): اطلاعات پروندهstat سیستم را چهار بار اجرا میکند، پس از فراخوانیهای جداگانه سریعتر نیست.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
کپی Copy
تابع کپی(src: رشته، dst: رشته): صحیحواردسازی سیستم پرونده.پرونده
تابع ریشه:
پرونده.نوشتن متن("اصلی.txt"، "سلام")
پرونده.کپی("اصلی.txt"، "رونوشت.txt")
پرونده.جابجایی("رونوشت.txt"، "جابهجا.txt")
پرونده.تغییر نام("جابهجا.txt"، "نهایی.txt")
سرچاپ پرونده.وجود دارد("رونوشت.txt")، پرونده.وجود دارد("نهایی.txt")، پرونده.خواندن متن("نهایی.txt")
پرونده.حذف("نهایی.txt")
سرچاپ پرونده.وجود دارد("نهایی.txt")
پایانجابجایی Move
تابع جابجایی(src: رشته، dst: رشته): صحیحپوشه.جابجایی میتواند بهجایش رونوشت بگیرد.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Copy.salam
تغییر نام Rename
تابع تغییر نام(src: رشته، dst: رشته): صحیحجابجایی است.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Copy.salam
حذف Delete
تابع حذف(p: رشته): صحیحخطا به شکل پرونده یافت نشد ثبت میشود.نمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Copy.salam
وجود دارد Exists
تابع وجود دارد(p: رشته): منطقینمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Stat.salam
هش امدی۵ Md5Hex
تابع هش امدی۵(p: رشته): رشتهواردسازی سیستم پرونده.پرونده
تابع ریشه:
پرونده.نوشتن متن("پیام.txt"، "abc")
سرچاپ پرونده.هش امدی۵("پیام.txt")
سرچاپ پرونده.هش شا۱("پیام.txt")
سرچاپ پرونده.هش شا۲۵۶("پیام.txt")
سرچاپ پرونده.هش شا۵۱۲("پیام.txt").طول()
پایانهش شا۱ Sha1Hex
تابع هش شا۱(p: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Sha256Hex.salam
هش شا۲۵۶ Sha256Hex
تابع هش شا۲۵۶(p: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Sha256Hex.salam
هش شا۵۱۲ Sha512Hex
تابع هش شا۵۱۲(p: رشته): رشتهنمونهی این مورد همراه با موارد بالاتر آمده است: fs-file-Sha256Hex.salam