• فایل باینری نوشتن و خواندن انواع داده های سفارشی در فایل های باینری

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

    ما سعی خواهیم کرد تا جایی که ممکن است همه چیز را توضیح دهیم. زبان ساده، زیرا چنین اطلاعاتی برای هر کاربر، حتی بی تجربه ترین، مفید است، زیرا آنها به طور مستقیم با اصول اولیه امنیت رایانه مرتبط هستند.

    کمی تئوری

    فایل متنی حاوی کاراکترهای ASCII است (مخفف عبارت American است کد استاندارد برای اطلاعات Interchange، چیزی شبیه «رمزگذاری استاندارد آمریکایی برای تبادل اطلاعات»).

    در واقع ASCII جدولی است که در آن به هر حرف، عدد، علامت نقطه گذاری و "سگ" های مختلف با "دانه های برف" (به معنای @ و *) یک بایت اختصاص داده شده است. یعنی هر کدام هشت صفر و یک (بیت). به علاوه، البته، کاراکترهایی مانند خط جدید را کنترل کنید.

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

    در یک فایل باینری، صفرها و یک ها به ترتیبی مرتب می شوند که برای نمایش متون ضروری نیستند (البته برخی از آنها، به عنوان مثال *doc) وجود دارد. و برای چه، شما بپرسید. پاسخ ساده است: هر چیز دیگری. برنامه ها، فیلم ها، موسیقی، تصاویر - هر فرمت اصول ساختاری خود را برای سازماندهی داده ها دارد.

    خود کلمه "دودویی" به معنای "متشکل از دو جزء"، "دوگانه" است. در واقع، تنها دو جزء را می توان به وضوح تعریف کرد - صفر و یک، بیت ها، "آجرها" که فایل را تشکیل می دهند. معنای هر چیز دیگری فقط در هنگام راه اندازی (باز کردن، پخش) ظاهر می شود.

    زیرین دنیای دیجیتال

    می توانید داخل فایل باینری را با برنامه ویژه- ویرایشگر HEX. (از کلمه هگزادسیمال به معنای سیستم اعداد هگزادسیمال است.) اینگونه نرم افزارها بایت ها را به شکل نامگذاری HEX خود نشان می دهند که در واقع به صورت جدول (ماتریس) نیز مرتب شده اند.

    به عنوان مثال، بایت های تصویر در فرمت JPEG، یک عکس یا عکس معمولی، در پنجره ویرایشگر به عنوان FF D8 FF 00 04 3A 29 و غیره نشان داده می شود.

    متخصص متوجه خواهد شد که توالی بایت FF D8 در همان ابتدا نشان می دهد که ما JPEG در مقابل خود داریم. و برای افراد غیر متخصص، این همه چیز جالب نیست.

    در ویرایشگر HEX می توانید و را باز کنید فایل متنیبرای دیدن اینکه کدام بایت با حروف خاص (کاراکترهای ASCII) مطابقت دارد. اما صرفاً از روی کنجکاوی، هنوز معنی ندارد.

    اما پرونده های باینری، اتفاقاً به شکل هگزادسیمال با اهداف کاملاً معنی دار و مشخصی مشاهده می شوند. به عنوان مثال، متخصصان آزمایشگاه های آنتی ویروس کدهای مخرب اضافه شده به کد اصلی را از این طریق جستجو می کنند. به هر حال، اجازه دهید به مسائل امنیتی برویم.

    چه چیزی می تواند آسیب برساند

    یک فایل متنی نمی تواند حاوی چیزی غیر از کاراکترهای ASCII باشد. با این حال، برنامه ها نه تنها باینری هستند، بلکه از نمادهای فوق نیز تشکیل شده اند. البته منظورم فیلمنامه است.

    به عبارت دیگر، فایل *txt اصولاً آلوده نیست و تهدیدی ایجاد نمی کند. و اگر یک اسکریپت در داخل فایل متنی وجود داشته باشد، می تواند دردسرهای زیادی ایجاد کند.

    به عنوان مثال، فایل *bat حاوی کد دستورات مختلف است و با دوبار کلیک کردن راه اندازی می شود برنامه منظم. این دستورات با کاراکترهای ASCII نوشته شده‌اند، اما سیستم عامل می‌تواند آنها را تفسیر کند - آنها را به صفر و یک‌هایی تبدیل کند که برای برنامه‌ها معمولی هستند.

    اما مطمئناً روی فایل‌های خفاش ناشناخته کلیک نمی‌کنید، درست است؟ خوبه.

    انتشارات قبلی:

    آخرین ویرایش: 2012-11-06 14:45:16

    برچسب های مواد: ,

    کار با فایل های باینری

    تمام اطلاعات به صورت 0 و 1 یعنی به صورت باینری در رایانه ذخیره می شود. فایل های باینری با فایل های متنی فقط در نحوه مدیریت آنها متفاوت است. به عنوان مثال، اگر عدد "4" را در یک فایل متنی بنویسیم، به صورت کاراکتر نوشته می شود و برای ذخیره آن به یک بایت نیاز است. بر این اساس حجم فایل برابر با یک بایت خواهد بود. فایل متنی حاوی ورودی: "145687" شش بایت خواهد بود.

    اگر عدد صحیح 145687 را در یک فایل باینری بنویسیم، اندازه آن چهار بایت خواهد بود، زیرا این مقدار برای ذخیره داده‌های نوع int نیاز است. یعنی باینری‌ها فشرده‌تر هستند و در برخی موارد پردازش آنها آسان‌تر است.

    نوشتن انواع داده های استاندارد در فایل های باینری

    برای باز کردن یک فایل باینری، باید حالت دسترسی را روی ios::binary تنظیم کنید (در برخی از کامپایلرهای C++، ios::bin).

    برای ایجاد یک فایل خروجی، یک شی ایجاد کنید:

    outstream outBinFile("out.bin", ios::out | ios::binary);

    /* ایجاد یک شی کلاسخارج از جریان بیرون صندوقچه

    اگر (! out_f و 1) //بررسی استاندارد

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

    مثال 1متغیرهای مختلف را در یک فایل باینری بنویسید:

    outstream outBinFile("test.bin"، ios::out I

    ios: :binary); /^ ایجاد شی کلاساز جریان و سعی کنید آن را به یک فایل پیوند دهیدتست. صندوقچه در حالت نوشتن باینری */

    int a - 145687; //اعلان یک متغیر عدد صحیحآ

    outBinFile. نوشتن ((char*) &a, sizeof(a)) ; /^نوشتن در فایل

    متغیرآ به عنوان یک جریان از بایت ها، یعنی نوشتن نمایش داخلی یک متغیر عدد صحیح در یک فایل a */ float x - 123.25; // اعلان متغیر واقعیایکس

    outBinFile .write ((char*) &x, sizeof(x)) ; /^نوشتن در فایل

    متغیرایکس به عنوان یک جریان از بایت، یعنی نوشتن نمایش داخلی یک متغیر عدد صحیح x*/ در یک فایل

    //تعریف متغیر کاراکتربا و مقداردهی اولیه آن با g outBinFile.write((char*)&c, sizeof(c));

    //ورود کاراکتر g برای تشکیل پرونده

    outBinFile.close(); بازگشت 0;

    اگر محتویات فایل test .bin را با یک ویرایشگر متن باز کنید، به شکل زیر خواهد بود:

    و حجم فایل 9 بایت خواهد بود.

    خواندن انواع داده های استاندارد از فایل های باینری

    برای باز کردن یک فایل باینری موجود برای خواندن، باید یک شی ایجاد کنید:

    ifstream inpBinFile("inp.bin", ios::in I ios::binary);

    /* از جدایی پرچم ها استفاده کنید که نشان می دهد فایل برای خواندن به صورت باینری باز شده است */

    if(!inpBinFile)

    cout برای خواندن داده ها از تابع read() استفاده می کنیم که پارامترهایی مشابه تابع write() دارد.

    #include using namespace std; int main()

    ifstream inpBinFile("test.bin"، ios::in I

    ios: :binary); / / فایل را برای خواندن به صورت باینری باز کنید

    int a; شناور x; char c = "g";

    inpBinFile.read((char*)&a, sizeof(a));

    //خواندن متغیر عدد صحیح inpBinFile.read((char*)&x, sizeof(x));

    //خواندن متغیر واقعی inpBinFile.read((char*)&c, sizeof(c));

    //خواندن متغیر کاراکتر

    inpBinFile.close(); کوت

    نتیجه برنامه:

    a = 145687 x = 123.25 c = g

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

    نوشتن و خواندن انواع داده های سفارشی در فایل های باینری

    بر خلاف فایل های متنی، کار با انواع داده های سفارشی با استفاده از فایل های باینری تفاوتی با انواع داده های استاندارد ندارد. از متدهای write() و read() به طور مشابه استفاده می شود. برنامه نویس فقط باید آدرس ناحیه حافظه ای که باید نوشته شود و تعداد بایت هایی که باید نوشته شود را مشخص کند، با در نظر گرفتن اینکه هیچ تبدیل داده ای رخ نمی دهد، فقط نمایش داخلی اطلاعات نوشته و خوانده می شود.

    همچنین هنگام کار با فایل های باینری می توان از متدهای seekg()، tellg()، seekp()، tellp() استفاده کرد.

    مثال 3برنامه ای بنویسید که اطلاعات گروهی از گردشگران را در یک فایل باینری بنویسد.

    fstream BinFile("ankety.bin", ios::in I ios::out | ios::binary);

    گروه پرسشنامه = ; برای (int i = 0; i

    BinFile.write((char*)&Gruppa[i], sizeof(Anketa)); BinFile.close(); بازگشت 0;

    مثال 4فایل "ankety.bin" حاوی داده هایی در مورد گروهی از گردشگران است، لازم است آنها را بخوانید و روی صفحه نمایش دهید.

    #include using namespace std; سوال ساختار (

    نام شخصیت؛ بین سن

    نوع داده های ساختاریپرسشنامه روی صفحه*/

    جریان و اپراتور

    fstream BinFile("ankety.bin", ios::in | ios::out | ios::binary); اگر (!BinFile)

    برای (int i = 0; i

    //بلافاصله تمام بایت های اشغال شده توسط متغیر نوع را بخوانید Anketa BinFile.read((char*)&Gruppa[i], sizeof(Anketa));

    BinFile.close(); بازگشت 0;

    نتیجه برنامه:

    ایوانف، 23 سیدوروف، 21 پتروف، 22

    کلیدی را برای ادامه فشار دهید. . .

    در حال توسعه کلاس های خود برای کار با فایل ها

    استفاده مدام از متدهای write() و read() ناخوشایند است، بسیار زیباتر است که بتوانید از عملیات ">" به صورت قیاس با فایل های متنی استفاده کنید. بیایید یک مثال از پیاده سازی کلاس خود برای کار با فایل های باینری ارائه دهیم.

    با استفاده از namespace std.

    سوال ساختار //اعلان ساختاری برای ذخیره اطلاعات

    /* بارگذاری بیش از حد عملیات درج در جریان برای خروجی سفارشی

    نوع داده های ساختاریپرسشنامه روی صفحه*/

    جریان و اپراتور

    کلاس outBinaryFile: عمومی از stream /^ کلاس خود را برای کار با فایل های باینری خروجی تعریف می کنیم. ما آن را از کلاس برای کار با جریان های فایل خروجی تولید می کنیم */

    /* هنگام توصیف سازنده کلاس تولید شده، فراموش نکنید که سازنده کلاس پایه را فراخوانی کنید و پارامترهای لازم را به آن منتقل کنید */

    outBinaryFile(char* name): ofstream(name, ios::out Ios::binary)

    //عملیات لازم را به عنوان متدهای کلاس اضافه بارگذاری کنیداپراتور outBinaryFile

    write((char*)&chislo, sizeof(chislo)); بازگشت *این;

    اپراتور outBinaryFile

    write((char*)&ank, sizeof(ank)); بازگشت *این;

    class inpBinaryFile: public if stream /* ما کلاس خود را برای کار با فایل های باینری ورودی تعریف می کنیم. ما آن را از کلاس برای کار با جریان های فایل ورودی تولید می کنیم */

    inpBinaryFile(char* name): ifstream(name, ios::in Ios::binary)

    /*سازنده کلاس پایه را با پارامترهای مورد نیاز فراخوانی کنید،

    برای سازنده کلاس مشتق شده کافی است */

    //عملیات لازم را اضافه بار کنید

    inpBinaryFile& operator >> (int& number)

    read((char*)&chislo, sizeof(chislo)); بازگشت *این;

    inpBinaryFile& operator >> (Anketa& ank)

    read((char*)&ank, sizeof(ank)); بازگشت *این;

    int a = 111، b = 112; outBinaryFile outFile("dannye.bin");

    // فایل را برای خواندن باز کنید

    inpBinaryFile inpFile("dannye.bin"); اگر (!inpFile)

    برای (int i = 0; i

    inpFile >> a; //پرسشنامه را از فایل بخوانید

    cout // و آن را روی صفحه نمایش دهید

    inpFile >> anketa; کوت

    نتیجه برنامه:

    کولیا، 1990، 582-78-95.

    کلیدی را برای ادامه فشار دهید. . .

    1. آیا امکان استفاده از عملیات در برنامه وجود دارد؟

    ios::در من ios::out

    • الف) بله، در هر صورت؛
    • ب) بله، اما فقط هنگام کار با فایل های متنی.
    • ج) نه، به هر حال.
    • 2. گزینه صحیح را برای باز کردن یک فایل متنی برای خواندن مشخص کنید:
      • الف) ifstream inpF("input.txt", ios::in);
      • ب) ifstream inpF("input.txt", ios::input);
      • ج) ifstream inpF(ios:in، "input.txt").

    ح- در نتیجه اجرای کد زیر چه چیزی نمایش داده می شود؟

    inputFile.get(c);

    بعدی - inputFile.peek();

    اگر (بعدی == EOF)

    • الف) محتویات فایل مرتبط با جریان inputFile یک بار نمایش داده می شود.
    • ب) محتویات فایل مرتبط با جریان inputFile روی صفحه نمایش داده می شود عدد بی نهایتیک بار؛
    • ج) چیزی روی صفحه نمایش داده نمی شود.
    • 4. چند کاراکتر در فایل وجود دارد؟
    • 12 3 4 5 6
    • الف) 6؛
    • ب) 7;
    • در ساعت 11
    • 5. چه روش هایی به شما اجازه می دهد تا پایان یک فایل را تعیین کنید؟
    • الف) eof();
    • ب) خوب ();
    • ج) هر دوی این روشها.
    • 6. هدف از تابع getline() چیست؟
    • الف) کلمه ای را از یک فایل می خواند.
    • ب) کل محتویات فایل را می خواند.
    • ج) یک خط از یک فایل را می خواند.
    • 7. برای نوشتن/خواندن انواع داده های تعریف شده توسط کاربر در یک فایل، باید:
      • الف) بارگذاری بیش از حد عملیات ">>" و "
      • ب) نوشتن و خواندن انواع داده های تعریف شده توسط کاربر بدون اقدامات اضافی در دسترس است.
      • ج) نوشتن و خواندن انواع داده های تعریف شده توسط کاربر در یک فایل امکان پذیر نیست.
    • 8. از چه توابعی برای نوشتن / خواندن اطلاعات به صورت باینری استفاده می شود؟
    • الف) printf/scanf
    • ب) نوشتن / خواندن؛
    • ج) قرار دادن / بدست آوردن.
    • 1. برنامه ای بنویسید که حروف الفبای انگلیسی را در یک فایل بنویسد.
    • 2. فایل input.txt حاوی اطلاعاتی از چندین خط متن است. محتویات این فایل را روی صفحه نمایش دهید، تعداد خطوط فایل را بشمارید.
    • 3. دیسک حاوی فایل result.txt با نتایج آزمایشات شیمیایی است. برنامه ای بنویسید که یک کپی از این فایل به نام copy_resylt.txt ایجاد کند.
    • 4. از صفحه کلید برای وارد کردن نام فایل استفاده کنید. که در فایل مشخص شدهتمام خطوط زوج را حذف کنید
    • 5. برنامه ای بنویسید که در یک فایل متنی، تمام حروف کوچک را با حروف بزرگ جایگزین کند و بالعکس.
    • 6. فایل متنی منبع حاوی اعدادی است که با فاصله از هم جدا شده اند. دو فایل جدید ایجاد کنید: اولی باید فقط شامل اعداد زوج باشد و دومی - فرد.
    • 7. فایل حاوی اعداد واقعی است. برنامه ای بنویسید که قسمت کسری این اعداد را حذف کرده و در یک فایل جدید بنویسد.
    • 8. اطلاعات مربوط به پروازهای خطوط هوایی در یک فایل متنی ثبت می شود. از این داده پروازهایی را که بعدازظهر حرکت می کنند انتخاب کنید و آنها را روی صفحه نمایش دهید.
    • 9. بیش از حد >> و عملگرها را بارگذاری کنید
    • 10. کلاس خود را برای کار با فایل های باینری بنویسید.
    • 11. لیستی از 10 دانش آموز در یک کلاس را در یک فایل متنی و یک فایل باینری بنویسید. این فایل ها را مقایسه کنید تفاوت حاصل را توضیح دهید.
    • 12. کلاسی ایجاد کنید که اطلاعات خودروها (سال ساخت، برند، رنگ و غیره) را در یک فایل متنی در یک فایل بنویسد. در این حالت هر نماد اطلاعات با کد ABO 1 خود جایگزین می شود. فایل حاصل را روی صفحه نمایش دهید.

    کنترل سوالات

    • 1. از چه کلاس هایی برای کار با جریان فایل استفاده می شود؟
    • 2. هنگام کار با فایل ها از چه حالت های دسترسی می توان استفاده کرد؟ مثال بزن.
    • 3. برای باز کردن فایل از چه روشی استفاده می شود؟ مثال بزن.
    • 4. چه عملیاتی برای کار با فایل ها موجود است؟ چه عملکردهایی برای انجام این عملیات طراحی شده است؟
    • 5. چه روش هایی به شما اجازه می دهد تا انتهای یک فایل را هنگام خواندن اطلاعات از آن تعیین کنید؟ تفاوت این روش ها چیست؟ مثال بزن.
    • 6. چگونه می توان متغیرهای انواع داده های استاندارد را از فایل های متنی خواند؟
    • 7. آیا می توان متغیرهای انواع داده های سفارشی را از فایل های متنی خواند؟
    • 8. چه توابعی برای خواندن تصادفی اطلاعات از یک فایل طراحی شده است؟ مثال بزن.
    • 9. ویژگی های فایل های باینری را نام ببرید. مزایای استفاده از چنین فایل هایی چیست؟
    • 10. از چه توابعی می توان برای نوشتن/خواندن اطلاعات در فایل های باینری استفاده کرد؟
    • 11. چگونه می توان متغیرهای انواع داده های استاندارد را از یک فایل باینری خواند؟
    • 12. هنگام خواندن انواع داده های سفارشی از فایل های باینری چه ملاحظاتی وجود دارد؟
    • "ایوانف"، 23)، ("سیدوروف"، 21)،

    توضیحات و نمایش داخلی فایل ها

    فایل ها متفاوت است. تمام فایل های ذخیره شده در کامپیوتر دارای ویژگی های خاصی هستند، به عنوان مثال. راه های خاصتوضیحات برای تشخیص یک فایل از فایل دیگر: 1) نام; سایز 2; 3) تاریخ و زمان؛ 4) نماد

    هر فایل یک نام دارد - نام فایل. نام فایل محتویات آن را توصیف می کند یا پیشنهاد می کند که برای چه مواردی می توان از آن استفاده کرد. هنگام ایجاد فایل، نام به آن اختصاص داده می شود. این برای همه فایل ها صدق می کند.

    هر فایل دارای اندازه فیزیکی است. فایل مقداری حافظه کامپیوتر و مقداری فضای دیسک را اشغال می کند.

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

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

    اندازه فایل درست مانند مقدار حافظه بر حسب بایت اندازه گیری می شود.

    اندازه فایل می تواند 0 بایت باشد، به این معنی که فایل وجود دارد، اما به خودی خود حاوی چیزی نیست. اس حداکثر اندازهفایل - 4 گیگابایت. اما چنین فایل های عظیمی بسیار نادر هستند.

    ساعت داخلی کامپیوتر مخصوصاً برای تعیین زمان و تاریخ ایجاد به فایل‌ها مورد نیاز است. این توضیح می دهد که چقدر مهم است که این ساعت را به درستی تنظیم کنید. برای مثال، ویژگی های اضافی برای توصیف فایل ها نیز وجود دارد فایل های سیستمی, فایل های مخفی، فایل های فقط خواندنی، فایل های آرشیوو غیره. سیستم عاملخودش باهاش ​​کنار بیاد

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

    فایل های متنی و باینری

    فایل‌ها به کاربر اجازه می‌دهند تا حجم زیادی از داده را مستقیماً از دیسک بدون تایپ کردن آن از صفحه کلید بخواند. دو نوع فایل اصلی وجود دارد: متن و باینری

    متنبه فایل های متشکل از هر کاراکتری گفته می شود. آنها در خطوطی سازماندهی شده اند که هر کدام با شخصیت ختم می شوند. آخر خط". انتهای خود فایل با علامت " نشان داده می شود. انتهای فایل". هنگام نوشتن اطلاعات در یک فایل متنی، که با استفاده از هر کدام قابل مشاهده است ویرایشگر متن، تمام داده ها به یک نوع کاراکتر تبدیل شده و به شکل کاراکتر ذخیره می شوند.

    به صورت دودویی ایکسفایل هااطلاعات در قالب بلوک هایی با اندازه مشخص خوانده و نوشته می شوند که می توانند داده ها را از هر نوع و ساختاری ذخیره کنند.

    برای کار با فایل ها از انواع داده های خاصی استفاده می شود که نامیده می شوند جریان هاجریان ifstream برای کار با فایل ها در حالت خواندن و ifstream در حالت نوشتن استفاده می شود. برای کار با فایل ها در هر دو حالت نوشتن و خواندن، از جریان ifstream استفاده می شود.

    در برنامه های ++C، هنگام کار با فایل های متنی، لازم است که کتابخانه های ifstream و iostream را در نظر بگیرید.

    برای نوشتن داده ها در یک فایل متنی، باید: 1) توصیف کنید متغیر نوع خارج از جریان باز کن; 3) خروجی اطلاعات به یک فایل. 4) حتما فایل را ببندید.

    برای خواندن داده ها از یک فایل متنی، باید:

    1) یک متغیر نوع را توصیف کنید ifstream; 2) فایل را با استفاده از تابع باز کنید باز کن; 3) خواندن اطلاعات از فایل، هنگام خواندن هر بخش از داده ها، لازم است بررسی شود که آیا به پایان فایل رسیده است یا خیر. 4) فایل را ببندید.

    لازم به ذکر است که در تمام مثال‌های مطرح شده در بالا، تابع ()fopen در حالت‌های r و w به ترتیب یک فایل متنی را برای خواندن و نوشتن باز می‌کند. این بدان معناست که برخی از کاراکترهای قالب‌بندی متن، مانند «\r» را نمی‌توان به عنوان نویسه‌های جداگانه خواند، مهم نیست که چگونه در فایل وجود دارند، اما وجود دارند. این یکی از ویژگی های حالت فایل متنی است. برای کار "زیبا" بیشتر با محتویات فایل ها، یک حالت باینری وجود دارد که محتویات یک فایل را به صورت دنباله ای از بایت ها نشان می دهد، که در آن همه کدهای کنترل ممکن فقط اعداد هستند. در این حالت است که می توان کاراکترهای کنترلی را که در حالت متنی موجود نیستند حذف یا اضافه کرد. برای باز کردن یک فایل در حالت باینری، تابع fopen() نیز با آخرین پارامتر به ترتیب برابر با "rb" و "wb" برای خواندن و نوشتن استفاده می شود.

    نمونه‌هایی که تاکنون در نظر گرفته‌ایم، ورودی/خروجی فرمت‌شده اطلاعات را به فایل‌ها نشان می‌دهند. توصیه می شود از ورودی/خروجی فایل های فرمت شده فقط در صورت کوچک و کوچک بودن اعداد و همچنین در صورت لزوم ارائه قابلیت مشاهده فایل ها بدون ابزارهای نرم افزاری. در غیر این صورت، البته استفاده از I/O باینری که اعداد را به همان شکلی که در رم کامپیوتر ذخیره می شود و نه به شکل آن ذخیره می کند، بسیار کارآمدتر است. رشته های کاراکتر. اجازه دهید یادآوری کنم که یک مقدار صحیح (int) یا واقعی (float) 4 بایت در حافظه اشغال می کند، یک مقدار دو برابر 8 بایت و یک مقدار کاراکتر است. از نوع char- 1 بایت به عنوان مثال، عدد 12345 در یک فایل متنی (فرمت شده) 5 بایت و در یک فایل باینری 4 بایت طول می کشد.

    باینری ها، یعنی فایل‌هایی که اطلاعات در آنها به شکل نمایش داخلی ذخیره می‌شود، برای استفاده بعدی توسط ابزارهای نرم‌افزاری استفاده می‌شوند؛ آنها را نمی‌توان با ابزارهای غیرنرم‌افزاری مشاهده کرد. مزیت فایل های باینری این است که اولاً هنگام خواندن / نوشتن، هیچ زمانی برای تبدیل داده ها از یک فرم نمایش نمادین به داخلی و بالعکس صرف نمی شود و ثانیاً دقت آن کاهش نمی یابد. اعداد واقعی. هم در مورد ورودی/خروجی فرمت شده و هم در مورد ورودی/خروجی باینری، برای پردازش «صحیح» اطلاعات از یک فایل، باید دانست که چه نوع داده‌هایی، چگونه و با چه ترتیبی نوشته شده‌اند. فایل باینری، به خصوص که مشاهده فایل باینری با ویرایشگر متن هیچ کاری انجام نمی دهد.

    مثالی را در نظر بگیرید که نوشتن عناصر عدد صحیح را نشان می دهد آرایه پویابه یک فایل باینری و خواندن آنها از آن فایل.

    #عبارتند از

    #عبارتند از

    #عبارتند از

    با استفاده از namespace std.

    کوت<< "Vvedite kol-vo elementov celochisl. massiva: "; cin >>N;

    int *mas = int[N] جدید;

    برای (i=0; i

    کوت<< " Vvedite " << i << "-i element: "; cin >> mas[i];

    کوت<< "\nIdet zapis dannyh v fail..." << endl;

    ofstream fout("c:\\os\\bin.dat", ios::binary);//ايجاد كردن. بیرون جریان باینری

    if(!fout) (cout<< "\n Oshibka otkrytiya faila!"; getch(); return 1; }

    fout.write(reinterpret_cast (mas)، N*sizeof(int));//نوشتن آرایه در فایل

    fout.close();//بستن جریان

    کوت<< "Dannye uspeshno zapisany!" << endl;

    برای (i=0; i

    ifstream fin("c:\\os\\bin.dat", ios::binary); //یک جریان برای خواندن فایل ایجاد کنید

    if(!fin) (cout<< "\n Oshibka otkrytiya faila!"; getch(); return 1; }

    کوت<< "Fail sodergit:" << endl;

    fin.read(reinterpret_cast (mas)، N*sizeof(int));//خواندن آرایه از فایل

    برای (i=0; i

    getch(); بازگشت 0;

    توجه ویژه ای در این برنامه باید به استفاده از توابع write() (روش کلاس ofstream) و read() (روش کلاس ifstream) معطوف شود. این توابع به داده ها بر حسب بایت فکر می کنند و برای انتقال تعداد مشخصی بایت از بافر داده به فایل و برگشت طراحی شده اند. پارامترهای این توابع آدرس بافر و طول آن بر حسب بایت است.

    تابع write() طوری طراحی شده است که تعداد بایت های مشخص شده در پارامتر دوم را از تعداد مشخص شده در پارامتر اول در فایل بنویسد. آدرس هابافر داده، و تابع read() برای خواندن داده ها از یک فایل طراحی شده است. در اینجا لازم به ذکر است که این توابع فقط با یک بافر داده از نوع char کار می کنند. در همین راستا در این برنامه از عملگر استفاده کردیم reinterpret_cast<> ، که بافر داده ما را از نوع int (mas) به بافری از نوع char تبدیل می کند.

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

    ofstream fout(نام فایل، ios::app | ios::binary);

    fout.write(reinterpret_cast (& cb)، sizeof(float));

    حال لازم است پارامتر دوم توابع در نظر گرفته شده را مورد بحث قرار دهیم. در این برنامه به عنوان پارامتر دوم از عبارت N * sizeof (int) استفاده کردیم که با آن تعداد بایت ها را محاسبه کردیم. برای مثال، اگر 5 عنصر آرایه صحیح داشته باشیم، تعداد بایت ها 20 خواهد بود. تابع sizeof() تعداد بایت های تخصیص داده شده برای نوع داده مشخص شده به عنوان پارامتر را برمی گرداند. به عنوان مثال، sizeof( بین المللی) برمی گردد 4.

    بنابراین، برنامه ارائه شده در این مثال به شما این امکان را می دهد که داده ها را به صورت باینری در فایل bin.dat بنویسید و آنها را از این فایل باینری بخوانید. علاوه بر این، پس از خواندن، این داده ها به نوع int تبدیل می شوند، ساختار یک آرایه را به دست می آورند و می توان هر عملیاتی را با آنها انجام داد.

    حال تصور کنید که باید برنامه ای بنویسید که به شما امکان خواندن داده ها از فایل bin.dat را می دهد و ما فقط می دانیم که این فایل حاوی عناصر یک آرایه عدد صحیح به صورت باینری است. تعداد عناصر ثبت شده (ن ) ما نمی دانیم. هنگام ایجاد یک برنامه، ما حق استفاده از یک آرایه ثابت را نداریم. در مرحله ایجاد برنامه برای آن حافظه اختصاص دهید. این یک نتیجه اشتباه خواهد داشت. از آنجایی که مقدار خیلی کوچک N منجر به این واقعیت می شود که همه عناصر آرایه در نظر گرفته نمی شوند و مقدار بسیار زیاد N منجر به پر کردن سلول های اضافی با مقادیر تصادفی می شود.

    نمونه ای از برنامه ای را در نظر بگیرید که به شما امکان می دهد با تخصیص دینامیک حافظه عناصر یک آرایه عدد صحیح را از یک فایل باینری بخوانید و برای اثبات واقعی بودن داده های خوانده شده، مجموع آنها را محاسبه کنید.

    #عبارتند از

    #عبارتند از

    #عبارتند از

    با استفاده از namespace std.

    int N, i, sum=0, dfb; //dfb - طول فایل بر حسب بایت

    ifstream fin("c:\\os\\bin.dat", ios:: باینری);

    if(!fin) (cout<< "Oshibka otkrytiya faila!"; getch(); return 1; }

    fin.seek(0, ios::end);//موقعیت خواندن را در انتهای فایل تنظیم کنید (از انتهای 0 بایت)

    dfb = fin.tellg();//دریافت مقدار موقعیت انتهای فایل (بر حسب بایت)

    N=dfb/4;//با دانستن اینکه یک عدد صحیح 4 بایت می گیرد، تعداد اعداد را محاسبه می کنیم

    int *arr = new int[N];// ایجاد یک آرایه پویا

    fin.seekg(0, ios::beg);//قبل از خواندن داده ها، موقعیت فعلی را به ابتدای فایل منتقل کنید

    fin.read(reinterpret_cast (arr)، dfb؛

    کوت<< "Iz faila schitano " << N << " elementov:" << endl;

    برای (i=0; i

    برای (i=0; i

    کوت<< "\n Ih summa = " << sum;

    getch(); بازگشت 0;

    بیایید نگاهی دقیق تر به این برنامه بیندازیم، که در آن به طور فعال از توابع seekg() و tellg() که متدهای کلاس ifstream هستند استفاده کردیم. در اینجا لازم به ذکر است که هر فایلی هنگام باز شدن با موقعیتی به اصطلاح خواندن یا نوشتن همراه است. هنگامی که یک فایل برای خواندن باز می شود، این موقعیت به طور پیش فرض در ابتدای فایل قرار می گیرد. اما اغلب اوقات لازم است موقعیت به صورت دستی کنترل شود تا بتوان از یک مکان دلخواه در فایل شروع به خواندن و نوشتن کرد. توابع seekg() و tellg() به شما امکان می دهند اشاره گر خواندن فعلی را تنظیم و بررسی کنید، در حالی که توابع seekp() و tellp() همین کار را برای اشاره گر نوشتن انجام می دهند.

    متد seekg(1_parameter, 2_parameter) موقعیت خواندن فعلی را از فایل با تعداد بایت های مشخص شده در 1_parameter نسبت به مکان مشخص شده در 2_parameter جابجا می کند. 2_parameter می تواند یکی از سه مقدار را بگیرد:

    ios::beg - از ابتدای فایل;

    ios::cur - از موقعیت فعلی؛

    ios::end - از انتهای فایل.

    در اینجا beg، cur و end ثابت هایی هستند که در کلاس ios تعریف شده اند و نمادهای:: یک عملیات دسترسی به این کلاس را نشان می دهند. مثلا اپراتور fin.seekg(-10, ios::end);به شما این امکان را می دهد که موقعیت خواندن فعلی را از فایل 10 بایت قبل از پایان فایل تنظیم کنید.

    حالا به توضیحات برنامه برگردیم. با توجه به اینکه تعداد اعداد نوشته شده در فایل را نمی دانیم، ابتدا باید تعداد اعداد را دریابیم. برای این، با استفاده از fin.seek(0, ios::end);به انتهای فایل می رویم و از تابع tellg() برای برگرداندن طول فایل بر حسب بایت به متغیر dfb استفاده می کنیم. تابع tellg() موقعیت فعلی اشاره گر را بر حسب بایت برمی گرداند. از آنجایی که طول یک عدد صحیح بر حسب بایت برای ما مشخص است (4 بایت)، محاسبه تعداد اعداد نوشته شده در فایل، با دانستن طول فایل بر حسب بایت، دشوار نیست. N=dfb/4;). با یادگیری تعداد اعداد، یک آرایه پویا ایجاد می کنیم و به ابتدای فایل می رویم تا با استفاده از تابع read () شروع به خواندن داده ها کنیم. پس از اینکه تعداد بایت های داده نشان داده شده توسط ما (dfb) به بافر داده (arr) منتقل شد، داده های خوانده شده به این ترتیب ساختار یک آرایه را به دست می آورند و برای هر گونه عملیات و تبدیل کاملاً مناسب می شوند.

    رکوردها)، پس کاملاً قابل درک است که بخواهیم مقدار حافظه استفاده نشده، اما اشغال شده را به نحوی کاهش دهیم.

    برای چنین مواردی وجود دارد ورودی های با یک قسمت متفاوت.

    ضبط توضیحات با قسمت متغیر

    در بخش var علامت گذاری با یک قسمت متفاوتآن را اینگونه توصیف کنید:

    var<имя_записи>: رکورد<поле1>: <тип1>; [<поле2>: <тип2>؛] [...] مورد<поле_переключатель>: <тип>از<варианты1>: (<поле3>: <тип3>; <поле4>: <тип4>; ...); <варианты2>: (<поле5>: <тип5>; <поле6>: <тип6>; ...)؛ [...] پایان؛

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

    قسمت متفاوتبا کلمه رزرو شده شروع می شود و پس از آن فیلد رکورد نشان داده می شود که بعداً به عنوان سوئیچ عمل می کند. مانند یک عبارت case معمولی، سوئیچ باید متعلق به یکی از موارد باشد انواع برشمرده شدهداده ها (به سخنرانی 3 مراجعه کنید). لیست انتخاب ها می تواند یک ثابت، یک محدوده یا ترکیب چندین ثابت یا محدوده باشد. مجموعه فیلدهایی که اگر گزینه مربوطه اجرا شده باشد باید در ساختار رکورد گنجانده شود در داخل پرانتز قرار می گیرد.

    مثال. برای توصیف محتوای کتابخانه، اطلاعات زیر مورد نیاز است:

    ستون های «عنوان» و «ناشر» برای هر سه گزینه مشترک هستند و فیلدهای باقیمانده به نوع انتشار بستگی دارد. برای پیاده سازی این ساختار از علامت گذاری با یک قسمت متفاوت:

    نوع biblio = نام رکورد، ناشر: string; مورد: char of "b": (نویسنده: رشته؛ سال: 0..2004); "n": (داده ها: تاریخ)؛ "m": (سال: 1700..2004؛ ماه: 1..12؛ تعداد: عدد صحیح)؛ پایان؛

    بسته به مقدار فیلد مورد، رکورد شامل 4، یا 5 یا 6 فیلد خواهد بود.

    مکانیزم برای استفاده از یک رکورد با یک قطعه متغیر

    تعداد بایت های اختصاص داده شده توسط کامپایلر برای علامت گذاری با یک قسمت متفاوت، با طولانی ترین نوع آن تعیین می شود. مجموعه فیلد "کوتاه تر" از سایر گزینه ها تنها کسری از حافظه اختصاص داده شده را اشغال می کند.

    در مثال بالا، گزینه "b" "طولانی ترین" است: به 23 بایت نیاز دارد (21 بایت برای یک رشته و 2 بایت برای یک عدد صحیح). گزینه های "n" و "m" به ترتیب به 4 و 5 بایت نیاز دارند (جدول را ببینید).

    نام، ناشر مورد قسمت متفاوت
    ... "ب" نویسنده سال
    ... "ن" داده ها
    ... "م" سال ماه عدد
    ... "ب" نویسنده سال

    باینری ها

    فایل های باینری اطلاعات را به شکلی که در حافظه کامپیوتر ارائه می شود ذخیره می کنند و بنابراین برای انسان ناخوشایند هستند. با نگاه کردن به چنین پرونده ای، درک آنچه در آن نوشته شده است غیرممکن است. نمی توان آن را به صورت دستی ایجاد یا اصلاح کرد - در برخی از ویرایشگرهای متن - و غیره. با این حال، تمام این ناراحتی ها با سرعت کار با داده ها جبران می شود.

    همچنین فایل های متنی ساختاری هستند دسترسی متوالی، و باینری - مستقیم. این بدان معنی است که در هر زمان می توانید به هر کسی مراجعه کنید، نه فقط عنصر فعلی.