شنبه ۲۹ دي ۱۴۰۳
Tut24 آموزش برنامه نویسی و مجله تخصصی فناوری ورود/عضویت

آموزش مبانی برنامه نویسی - ورودی/خروجی فایل

فایل‌های کامپیوتر

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

فایل‌های کامپیوتر می‌توانند به عنوان معادل دیجیتال سند های کاغذی در نظر گرفته شوند. در هنگام برنامه‌نویسی، کدهای منبع خود را در فایل‌های متنی با پسوند‌های مختلف نگه می‌دارید. به عنوان مثال، فایل‌های برنامه‌نویسی C با پسوند .c، فایل‌های برنامه‌نویسی جاوا با پسوند .java و فایل‌های پایتون با پسوند .py پایان می‌یابند.

ورودی/خروجی فایل

معمولاً، فایل‌ها با استفاده از ویرایشگرهای متنی مانند notepad، MS Word، MS Excel یا MS Powerpoint و غیره ایجاد می‌شوند. با این حال، بسیاری اوقات، نیاز به ایجاد فایل‌ها با استفاده از برنامه‌های کامپیوتری داریم. می‌توانیم با استفاده از برنامه کامپیوتری، یک فایل موجود را ویرایش کنیم.

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

در حال حاضر، کافیست به خاطر بسپارید که نوشتن در یک فایل، ورودی فایل است و خواندن چیزی از یک فایل، خروجی فایل است.

حالت‌های عملیاتی فایل

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

  • حالت فقط خواندنی (Read-Only Mode) - اگر شما فقط می‌خواهید یک فایل موجود را بخوانید و نمی‌خواهید هیچ محتوای جدیدی به فایل بنویسید، آنگاه فایل را در حالت فقط خواندنی باز می‌کنید. تقریباً تمام زبان‌های برنامه‌نویسی، سینتکس (دستورات) برای باز کردن فایل در حالت فقط خواندنی فراهم می‌کنند.

  • حالت فقط نوشتنی (Write-Only Mode) - اگر شما می‌خواهید به یک فایل موجود یا یک فایل جدید بنویسید، اما نمی‌خواهید هیچ محتوایی را از آن بخوانید، آنگاه فایل را در حالت فقط نوشتنی باز می‌کنید. تمام زبان‌های برنامه‌نویسی، سینتکس (دستورات) برای باز کردن فایل در حالت فقط نوشتنی فراهم می‌کنند.

  • حالت خواندن و نوشتن (Read & Write Mode) - اگر شما می‌خواهید به فایلی خوانده و در همان زمان به آن بنویسید، فایل را در حالت خواندن و نوشتن باز می‌کنید.

  • حالت افزودن (Append Mode) − هنگام باز کردن یک فایل برای نوشتن، به شما اجازه می دهد که از ابتدای فایل نوشتن را شروع کنید؛ با این حال، در صورت وجود، محتوای موجود را بازنویسی خواهد کرد. فرض کنید ما نمی خواهیم محتوای موجودی را بازنویسی کنیم، در این صورت فایل را در حالت افزودن باز می کنیم. حالت افزودن در واقع یک حالت نوشتن است که به ما اجازه می دهد محتوا را در انتهای فایل الحاق کنیم. تقریباً تمام زبان های برنامه نویسی، دستورالعمل های لازم برای باز کردن فایل در حالت افزودن را ارائه می دهند.

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

باز کردن فایل‌ها

می‌توانید از تابع fopen() برای ایجاد یک فایل جدید یا باز کردن یک فایل موجود استفاده کنید. این تابع یک شیء از نوع FILE را مقداردهی اولیه می‌کند که تمام اطلاعات لازم برای کنترل جریان را در خود دارد. پیش‌نویس (signature) این تابع به صورت زیر است:

FILE *fopen( const char * filename, const char * mode );

در اینجا، نام فایل یک رشته لیترال است که برای نام‌گذاری فایل و دسترسی به آن استفاده خواهید کرد و حالت می‌تواند یکی از مقادیر زیر را داشته باشد:

شماره حالت و شرح
۱

r

برای خواندن فایل متنی موجود باز می‌شود.

۲

w

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

۳

a

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

۴

r+

برای خواندن و نوشتن در فایل متنی باز می‌شود.

۵

w+

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

۶

a+

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

بستن فایل

برای بستن فایل، از تابع fclose() استفاده کنید. نمونه این تابع به صورت زیر است −

 int fclose( FILE *fp );

تابع fclose( ) صفر را در صورت موفقیت و یا نماد ویژه EOF در صورت وجود خطا در بستن پرونده برمی‌گرداند. این تابع در واقع هر داده‌ای که هنوز در بافر باقی مانده باشد را به پرونده خروجی منتقل می‌کند، پرونده را می‌بندد و هر حافظه‌ای که برای پرونده استفاده شده است را آزاد می‌کند. EOF یک ثابت در فایل هدر stdio.h تعریف شده است.

تعدادی تابع از کتابخانه استاندارد C برای خواندن و نوشتن یک پرونده بر اساس کاراکتر و یا به شکل رشته با طول ثابت ارائه شده است. بیایید چندین تابع از آنها را در بخش بعدی ببینیم.

نوشتن در پرونده

تابع ساده‌ترین برای نوشتن هر کاراکتر به یک جریان زیر آمده است −

int fputc( int c, FILE *fp );

تابع fputc() مقدار حرفی پارامتر c را به جریان خروجی مرجع شده توسط fp می‌نویسد. در صورت موفقیت، حرف نوشته شده بازگشت داده می‌شود و در غیر این صورت EOF اگر خطا وجود داشته باشد. شما می‌توانید از توابع زیر برای نوشتن یک رشته ترمینه نشده به یک جریان استفاده کنید −

int fputs( const char *s, FILE *fp );

تابع fputs() رشته s را در فایل مرجع fp می‌نویسد. اگر عملیات موفق باشد، یک مقدار غیر منفی برگشت داده می‌شود، در غیر این صورت EOF در صورت وجود هرگونه خطا برگشت داده می‌شود. شما همچنین می‌توانید از تابع int fprintf(FILE *fp,const char *format, ...) برای نوشتن یک رشته در فایل استفاده کنید. به مثال زیر مراجعه کنید −

#include <stdio.h>

int main() {
   FILE *fp;

   fp = fopen("/tmp/test.txt", "w+");
   fprintf(fp, "This is testing for fprintf...\n");
   fputs("This is testing for fputs...\n", fp);
   fclose(fp);
}

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

خواندن یک فایل

تابع ساده‌ترین برای خواندن یک فایل متنی کاراکتر به کاراکتر به صورت زیر است:

int fgetc( FILE * fp );

تابع fgetc() کاراکتری را از فایل ورودی مرجع با fp می‌خواند. مقدار بازگشتی کاراکتر خوانده شده است. در صورت بروز خطا، مقدار EOF برگشت داده می‌شود. تابع زیر به شما امکان می‌دهد یک رشته را از یک جریان خواندنی بخوانید −

char *fgets( char *buf, int n, FILE *fp );

تابع fgets() تا n-1 کاراکتر از جریان ورودی ارجاع شده توسط fp را می‌خواند. این رشته خوانده شده را در بافر buf کپی می‌کند و یک کاراکتر null را به پایان رشته اضافه می‌کند تا رشته ترمینیت شود.

اگر این تابع به کاراکتر جدید خط '\n' یا EOF قبل از خواندن حداکثر تعداد کاراکترها برخورد کند، آنگاه فقط کاراکترهای خوانده شده تا آن نقطه شامل کاراکتر جدید خط برمی‌گرداند. همچنین می‌توانید از تابع int fscanf(FILE *fp, const char *format, ...) برای خواندن رشته‌ها از یک فایل استفاده کنید، اما پس از برخورد با اولین کاراکتر فضای خالی خواندن را متوقف می‌کند.

#include <stdio.h>

main() {

   FILE *fp;
   char buff[255];

   fp = fopen("/tmp/test.txt", "r");
   fscanf(fp, "%s", buff);
   printf("1 : %s\n", buff );

   fgets(buff, 255, (FILE*)fp);
   printf("2: %s\n", buff );
   
   fgets(buff, 255, (FILE*)fp);
   printf("3: %s\n", buff );
   fclose(fp);
}

زمانی که کد بالا کامپایل و اجرا می‌شود، فایل ایجاد شده در بخش قبل را خوانده و نتیجه‌ی زیر را تولید می‌کند −

1 : This
2 : is testing for fprintf...

3 : This is testing for fputs...

بیایید بررسی کنیم که اینجا چه اتفاقی افتاد. ابتدا روش fscanf () کلمه "This" را خوانده است زیرا پس از آن با یک فضا مواجه شده است. فراخوانی دوم برای fgets () است که خط باقی مانده تا پایان خط را می‌خواند. در نهایت ، فراخوانی آخر fgets () کل دوم خط را به صورت کامل می‌خواند.

فایل I/O در جاوا

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

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

import java.io.*;

public class DemoJava {
   public static void main(String []args) throws IOException {
      File file = new File("/tmp/java.txt");
      
      // Create a File
      file.createNewFile();
      
      //  Creates a FileWriter Object using file object
      FileWriter writer = new FileWriter(file); 
      
      // Writes the content to the file
      writer.write("This is testing for Java write...\n");
      writer.write("This is second line...\n");
      
      // Flush the memory and close the file
      writer.flush();
      writer.close();
      
      // Creates a FileReader Object
      FileReader reader = new FileReader(file); 
      char [] a = new char[100];
      
      // Read file content in the array
      reader.read(a);
      System.out.println( a );
      
      // Close the file
      reader.close();
   }
}

هنگام اجرای برنامه بالا، نتیجه زیر را تولید می کند −

This is testing for Java write...
This is second line...

ورود و خروجی فایل در پایتون

برنامه زیر همان کارکرد برنامه قبلی را دارد، یعنی باز کردن یک فایل جدید، نوشتن برخی محتوا در آن و در نهایت، خواندن همان فایل را نمایش می‌دهد:

# Create a new file
fo = open("/tmp/python.txt", "w")

# Writes the content to the file
fo.write( "This is testing for Python write...\n");
fo.write( "This is second line...\n");

# Close the file
fo.close()

# Open existing file
fo = open("/tmp/python.txt", "r")

# Read file content in a variable
str = fo.read(100);
print str

# Close opened file
fo.close()

زمانیکه کد فوق اجرا می‌شود، خروجی زیر تولید می‌شود −

This is testing for Python write...
This is second line...