فایلهای دودویی در پایتون - متدهای bytes و bytearray

زمانی که با ویرایشگرهای متنی مانند vim یا notepad فایلی را می سازید، این فایل یک Plain Text File است. در ویندوز پسوند این فایل ها txt است ولی در سیستم عامل های یونیکسی مانند لینوکس و مکینتاش بایدی برای داشتن پسوند txt نیست. دسته دیگر از فایل ها، فایل های دودویی (binary) هستند که آنها نیز در برگیرنده کاراکترها هستند ولی این کاراکترها همانند txt فایل ها یا فایل های CSV و JSON و XML دیگر برای انسان قابل درک شدن نیستند.دسته بسیاری از فایل های دودویی مانند فایل Word و Excel و فایل های تصویری و صوتی و همچنین فایل های پشتیبان اوراکل و دیگر نمونه ها هستند. تفاوت اصلی فایل های دودویی با فایل های متنی ساده، در این است که فایل ها نخست بدست انسان قابل فهمیده شدن و از این رو، خوانده شدن نیستند. همچینن این فایل ها تنها بدست برنامه های ویژه خودشان خوانده می شوند. برای نمونه، فایل های پشتیبان پایگاه داده اوراکل، تنها بدست ابزار rman (یا Recovery Manager) خوانده می شوند.تابع Bytesکد زیر الگوی این تابع را نشان می دهد و آرگومان یکم آن می تواند یک توالی از شمارهای میان 0 تا 255 باشد که سپس به کمک ()bytes به بایت های همسان هر درایه از توالی تبدیل می شوند. برای نمونه می توانیم یک لیست از شماره های را بفرستیم، به شرطی که شماره هر دارایه شماره صحیح میان 0 تا 255 باشد. نه منفی، نه ممیز شناور و نه بیشتر از 255bytes([source[, encoding[, errors]]])در کد زیر نخست یک list از شماره های میان بازه 0 تا 255 ساخته و سپس به تابع ()bytes فرستاده می شود و برگشتی تابع ()bytes در متغیری به نام buffer نگهداری می شود. تابع ()print درون مایه متغیر buffer را نشان می دهد که شماره های هگزا دسیمال هستند. در خروجی زیر، b آغازین نشان می دهد که توالی از byte ها داریم. بنابراین تابع ()bytes یک توالی ورودی را به یک توالی از بایت ها نگاشت می دهد.b'\xff\x1e4\n\x00'برای نمونه، شماره هگزا دسیمالِ، شماره دهدهی 255 برابر با 0XFF است که در شکل زیر نشان داده شده است. در نمایش شماره ها در مبنای 16، در آغاز شماره یک 0X یا 0x گذاشته می شود. بازه شماره ها از 0 تا 9 و از A تا F (یا a تا f) است.توجه کنید اگر در آرگومان یکم، به جای یک لیست یا توالی از شماره ها، یک تک شماره مانند 10 بفرستیم، پس 10 بایت 0X00 ساخته می شود که هر 0X00 نشان دهنده شماره صفر در مبنای 16 است در واقع در اینجا تک شماره، برابر با اندازه بایت هایی است که ساخته می شود.در کد زیر، متغیری به نام filename ساخته ای که قرار است درون مایه متغیر buffer را در خودش نگه دارد. سپس به کمک عبارت with … as و تابع ()open، فایل متغیر filename به شیوه wb یا Write Binary باز و سپس محتوای بافر در آن نوشته و در پایان فایل بسته می شود.این فایل که در اینجا binfile نام دارد را نمی توانید با هیچ ویرایشگری باز کنید. در لینوکس دستوری به نام hexdump است که مسیر فایل باینری را دریافت و سپس درون آن را نشان می دهد. توجه کنید که این فایل دودویی می تواند برای نمونه یک تصویر jpg نیز باشد. چنین دستوری در ویندوز از پیش نیست ولی دستور نمونه و هم نام را می توانید از اینجا دانلود کند.hexdump.exe "C:\Users\amirnami\Python Projects\binfile"در پایتون نیز می توانید همانند کد زیر به کمک تابع ()open و به شیوه rb (یا Read Binary) فایل دودویی را بخوانید. سپس محتوای بدست آمده که به گونه (نوع) byte است را در متغیری به نام bcontent نگهداری می کنیم و سپس در یک حلقه for و به کمک تبدیل گونه (نوع) با کمک تابع ()int، هر شماره هگزا دسیمال را به شماره دهدهی نگاشت می دهیم.تابع bytearrayاین تابع همانند bytes است ولی با این تفاوت که متغیری که از روی bytearray ساخته می شود را می توانیم تغییر دهیم (Mutable) ولی متغیری که از روی bytes ساخته می شود غیر قابل تغییر (Imutable) است. در کد زیر توالی از کاراکترها، یعنی یک رشته ساخته ایم و سپس آن را به کمک bytearray به شیوع کدگذاری UTF-8 به بایت هایی نگاشت داده ایم. توجه کنید در اینجا درون مایه buffer2 یک رشته نیست بلکه به گونه بایت (byte) است و اگر بخواهیم با درون مایه buffer2 به شیوه رشته (str) رفتار کنیم، باید آن را از byte به str ببریم.bytearray(b'http://pythonprogramming.ir')تبدیل بایت به رشتهبرای این کار دو شیوه هست، شیوه نخست آنکه از متدی به نام ()decode کمک بگیریم که بدست همه شی های bytes در دسترس است. در کد زیر نخست بررسی می شود که آیا گونه متغیر buffer2 آیا str یا رشته است (buffer2 is str که از عملگر is کمک گرفته ایم). اگر اینگونه باشد که هیچ، دیگر ینازی به تبدیل گونه نیست ولی اگر str نبود (و با شرط اینکه در مسئله ما یا str است یا byte) پس به کمک متد ()decode که به کمک متغیر buffer2 در دسترس است، متغیری تازه به نام string_buffer ساخته ایم که نتیجه کدگذاری UTF-8 است. در همان خط شیوه دوم را نشان داده ایم که از تابع ()str و تبدیل گونه (نوع) کمک گرفته ایم.string_buffer = buffer2.decode("utf-8") string_buffer = str(buffer2, "utf-8") https://virgool.io/@linux_internals/%D8%A7%D8%AC%D8%B1%D8%A7%DB%8C-%D9%81%D8%A7%DB%8C%D9%84-%D8%B5%D9%88%D8%AA%DB%8C-wav-%D8%A8%D8%A7-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%D8%AF%D8%B1-%D9%88%DB%8C%D9%86%D8%AF%D9%88%D8%B2-usdusqhhaht9 https://virgool.io/@linux_internals/%D9%85%D8%A7%DA%98%D9%88%D9%84-struct-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-luhj0jgce19z دانلود اسکریپت