C Fayllar

C tilining asosiy xususiyatlaridan biri oldindan rejalashtirilgan fayllar strukturasi yo’qligidir. Hamma fayllar, baytlar ketma-ketligi deb ko’riladi. UNIX operasion sistemasida har bir qurilmaga «Maxsus fayl» mos keladi, shuning uchun C bibliotekasidagi funksiyalar fayllar bilan ham, qurilmalar bilan ham ma’lumot almashinishi uchun foydalaniladi. C tili bibliotekasida kiritish–chiqarish, quyi darajadagi kiritish, chiqarish va portlar uchun kiritish–chiqarish, oqimli daraja tizim xususiyatlariga bog’liq bo’lishi uchun bu yerda qaralmaydi.

Oqimli kiritish va chiqarish.

Oqimli chiqarish va kiritishda ma’lumotlar bilan almashish baytma-bayt amalga oshiriladi. Lekin tashqi xotira qurilmalari bilan almashish oldidan belgilangan ma’lumotlar bloki orqali amalga oshiriladi. Odatda bu blokning minimal hajmi 512 yoki 1024 baytga teng bo’ladi. Diskdan ya’ni fayldan o’qishda ma’lumotlar operasion tizim buferiga yoziladi, so’ngra baytma-bayt yoki ma’lum porsiyalar bilan foydalanuvchi dasturiga uzatiladi. Diskka ya’ni faylga yozishda buferga yig’iladi, so’ngra diskka bir murojaat qilinganda yagona blok sifatida uzatiladi. Buferlar operativ xotira qismlari sifatida yaratiladi, shuning uchun ma’lumot almashishi diskka to’g’ridan-to’g’ri murojaat qilishiga ko’ra tezroq amalga oshadi. Shunday qilib oqim bu buferlash vositalari va fayldir.

Oqim bilan ishlashda quyidagi vazifalarni bajarish mumkin.

  • Oqimlarni ochish va yopish;
  • Simvol, qator, satr, formatlangan ma’lumot ixtiyoriy uzunlikdagi ma’lumotlarni kiritish yoki chiqarish va fayl oxiriga yetganlik shartini tahlil qilish;
  • Buferlash va bufer hajmini boshqarish;
  • Ko’rsatkich oqimdagi o’rnini aniqlash yoki yangi o’ringa ko’chirish.

Bu vazifalarni bajaruvchi funksiyalardan foydalanish uchun dasturga stdio.h – faylini ulash lozim. Dastur bajarilishi boshlanganda avtomatik ravishda quyidagi oqimlar ochiladi:

  • Standart kiritish oqimi stdin;
  • Standart chiqarish oqimi stdout;
  • Xatolar haqida ma’lumotlar standart oqimi stderr;

Oqimlarni ochish va yopish. Oqim ochilishi uchun, oldindan kiritilgan FILE turidagi struktura bilan bog’lash lozimdir. FILE strukturasi ta’rifi stdio.h bibliotekasida joylashgan. Bu strukturada buferga ko’rsatkich, o’qilayotgan pozisiyaga ko’rsatkich va boshqa ma’lumotlar saqlanadi. Oqim ochilganda dasturga oqimga ko’rsatkich, ya’ni FILE strukturali turdagi ob’ektga ko’rsatkich qaytariladi. Bu ko’rsatkich quyidagicha e’lon qilinishi lozim.

FILE * <ko’rsatkich nomi>

Misol uchun: FILE * fp

Oqim ochish funksiyasi quyidagi ko’rinishga ega;

<oqimga korsatkich nomi> = fopen(<fayl-nomi>,<ochish rejimi>)

Misol uchun:

fp = fopen(“t.txt”, “r”)

Oqim bilan bog’liq faylni quyidagi rejimlarda ochish mumkin:

  1. “w”- Yangi fayl o’qish uchun ochiladi. Agar fayl mavjud bo’lmasa yangidan yaratiladi.
  2. “r” - Mavjud fayl faqat o’qish uchun ochiladi.
  3. “a” - Fayl da’vom ettirish uchun ochiladi.
  4. “w+” - Fayl yozish va keyingi taxrirlash uchun ochiladi. Fayl ixtiyoriy joyidan o’qish yoki yozish mumkin.
  5. “r+”- fayl ixtiyoriy joyidan o’qish yoki yozish mumkin, lekin fayl oxiriga qo’shish mumkin emas.
  6. “a+” - Fayl ixtiyoriy joyidan o’qish va yozish uchun ochiladi. Quyidagi “w+” rejimdan farqli fayl oxiriga ma’lumot qo’shish mumkin.

Matnli rejimda oqimdan o’qilgan quyidagi simvollar CR (qiymati 13) “karetkani qaytarish” va LF( qiymati 10)- “yangi qator boshiga o’tish” bitta simvolga “\n” (qiymati LF ya’ni 10ga teng) simvolga almashtiradi. Agar fayl matnli emas ixtiyoriy ma’lumotni saqlasa binar rejimda ochiladi. Buning uchun rejimlar belgilariga b harfi qo’shiladi, masalan “wb” yoki “r+b”. Ba’zi kompilyatorlarda matnli rejim t harfi yordamida ko’rsatiladi masalan ”rt”. Oqim ochilganda quyidagi xatolar kelib chiqishi mumkin: ko’rsatilgan fayl mavjud emas (o’qish rejimida); disk to’la yoki yozishdan himoyalangan va hokazo. Yana shuni aytish kerakki fopen() funksiyasi bajarilganda dinamik xotira ishlatiladi. Agar xotirada joy qolmagan bo’lsa “not enough memory ” - xatosi kelib chiqadi. Ko’rsatilgan xollarda ko’rsatkich NULL qiymatga ega bo’ladi. Bu xatolar haqidagi ma’lumotlarni ekranga chiqarish uchun perror() funksiyasi ishlatiladi. Bu funksiya stdio.h bibliotekasida saqlanuvchi prototipi quyidagi ko’rinishga ega.

void perror(const char * s);

Diskda ochilgan fayllarni berkitish uchun quyidagi funksiyadan foydalaniladi.

int fclose (<oqimga-ko’rsatkich nomi>).

Faylga ketma-ket murojaat qilish

Fayllar bilan ishlashning bitli rejimi. Fayl bilan bitli almashish rejimi getc() va putc() funksiyalari yordamida tashkil etiladi. Bu funksiyalarga quyidagi shaklda murojaat etiladi: c = getc(fp); putc(c,fp); Bu yerda fp-ko’rsatkich c-int turidagi o’zgaruvchi. Misol tariqasida klaviaturadan simvol kiritib faylga yozishni ko’ramiz. Matn oxirini ‘#’ belgisi ko’rsatadi. Fayl nomi foydalanuvchidan so’raladi. Agar <enter> klavishasi bosilsa faylga CR va LF (qiymatlari 13 va 10) konstantalar yoziladi. Keyinchalik fayldan simvollarni o’qishda bu konstantalar satrlarni ajratishga imkon beradi.

#include <stdio.h>
void main()
{
    FILE *fp;
    char c;
    const char CR = '\015';
    const char LF = '\012';
    char fname[20];
    puts("fayl nomini kiriting:\n");
    gets(fname);
    if((fp = fopen(fname, "w")) == NULL)
    {
    perror(fname);
    return 1;
    }
    while ((c = getchar())! = '#')
    {
        if (c == '\n')
        {
            putc(CR,fp);
            putc(LF,fp);
        }
        else putc (c,fp);
    }
    fclose(fp);
}

Keyingi programma fayldan simvollarni o’qib ekranga chiqaradi:

#include <stdio.h> 
#include <conio.h> 
int main()
{
    FILE *fp;
    char c;
    char fname[20];
    puts("fayl nomini kiriting:\n");
    gets(fname);
    if((fp = fopen(fname, "r")) = = NULL)
    {
        perror(fname);
        return 1;
    }
    while ((c = getc(fp))! = EOF) putchar(c);
    fclose (fp);
    getch();
}

Satrlar yordamida fayllar bilan bog’lanish. Matnli fayllar bilan ishlash uchun fget va fputs funksiyalaridan foydalaniladi. Bu funksiyalar prototiplari stdio.h faylida quyidagi ko’rinishga ega:

int fputs (const char *s, FILE *stream);
char *fgets (char * s, int n, FILE * stream);

fputs funksiyasi ‘\0’ simvoli bilan chegaralangan satrni stream ko’rsatkichi orqali aniqlangan faylga yozadi. ‘\0’ simvoli faylga yozilmaydi. fgets() funksiyasi stream ko’rsatkichi orqali aniqlangan fayldan (n-1) simvolni o’qiydi va S ko’rsatgan satrga yozib qo’yadi. Funksiya n-1 simvolni o’qib bo’lsa yoki 1-chi qator simvoli ‘\n’ ni uchratsa ishini to’xtatadi. Har bir satr oxiriga qo’shimcha ‘\0’ belgisi qo’shiladi. Xato bo’lganda yoki fayl oxiriga yetganda agar fayldan birorta simvol o’qilmagan bo’lsa NULL qiymat qaytariladi. Misol tariqasida fayl nomi foydalanuvchidan so’rab yaratuvchi va bu faylga ikkita kiritilgan so’zni yozib qo’yuvchi programmani ko’rib chiqamiz:

#include <stdio.h>
#include <conio.h>
void main()
{
    FILE *fp;
    char s[256];
    char fname[20];
    int n;
    puts("fayl nomini kiriting:\n");
    gets(fname);
    if((fp = fopen(fname, "w")) == NULL)
    {
        perror(fname);
        getch();
        return;
    }
    for(n = 1; n<3; n++)
    {
        gets(s);
        fputs(s,fp);
        fputs("\n",fp);
    }
    fclose(fp);
    getch();
}

Keyingi misolda nomi kiritilgan fayldan monitorga o’qishni ko’ramiz:

#include <stdio.h> 
#include <conio.h> 
void main()
{
    FILE *fp;
    char s[256];
    char fname[20];
    int n;
    puts("fayl nomini kiriting:\n");
    gets(fname);
    if((fp = fopen(fname, "r")) == NULL)
    {
        perror(fname);
        getch();
        return;
    }
    for(n = 1; n<3; n++)
    {
        fgets(s,256,fp);
        puts(s);
    }
    fclose(fp);
    getch();
}

Quyidagi dasturda bir fayldagi matnni ikkinchi faylga yozishni ko’rib chiqamiz.

Programma matni:

#include <stdio.h>
#include <conio.h>
void main()
{
    FILE *f1,*f2;
    char s[256];
    char fname1[20];
    char fname2[20];
    puts("fayl nomini kiriting:\n");
    gets(fname1);
    if((f1 = fopen(fname1, "r")) == NULL)
    {
        perror(fname1); getch();
        return;
    }
    puts("fayl nomini kiriting:\n");
    gets(fname2);
    if((f1 = fopen(fname2, "w")) == NULL)
    {
        perror(fname2); getch();
        return;
    }
    while (fgets(s,256,f1)! = NULL) fputs(s,f2);
    fclose(f1);
    fclose(f2);
    getch();
}

Fayllar bilan formatli almashinuv. Ko’p hollarda ma’lumotni to’g’ridan to’g’ri monitorga chiqarishda qulay shaklda faylda saqlash zarur bo’ladi. Bu holda faylga formatli kiritish va chiqarish funksiyalaridan foydalanish mumkin. Bu funksiyalar quyidagi prototiplarga ega:

  • int fprintf (oqimga ko’rsatkich, formatlash-qatori, o’zgaruvchilar ro’yxati);
  • int fscanf (oqimga ko’rsatkich, formatlash-qatori, o’zgaruvchilar ro’yxati);

Misol tariqasida fayl nomi foydalanuvchidan so’rab yaratuvchi va bu faylga 1 dan 100 gacha bo’lgan sonlarning simvolli tasvirini yozib qo’yuvchi programmani ko’rib chiqamiz:

#include <stdio.h>
void main()
{
    FILE *fp;
    int n;
    char fname[20];
    puts("fayl nomini kiriting:\n");
    gets(fname);
    if((fp = fopen(fname, "w")) == NULL)
    { 
        perror(fname);
        return;
    }
    for(n = 1; n<11; n++)
    fprintf(fp,"%d ",n);
    fclose(fp);
}

Keyingi misolda nomi kiritilgan fayldan monitorga o’qishni ko’ramiz:

#include <stdio.h>
#include <conio.h>
void main()
{
    FILE *fp;
    int n;
    char fname[20];
    puts("fayl nomini kiriting:\n");
    gets(fname);
    if((fp = fopen(fname, "r")) == NULL)
    {
        perror(fname);
        getch();
        return;
    }
    for(n = 1; n<11; n++) 
    {
    fscanf(fp,"%d ",&n);
    printf("%d ",n);
    }
    fclose(fp);
    getch();
}

Standart oqimga chiqarish. Keyingi dasturda satrlarni standart kiritish oqimi ya’ni klaviaturadan kiritish va standart chiqarish oqimiga, monitorga chiqarish ko’rsatilgan:

#include<stdio.h>
#define MAXLINE 20 
int main(void)
{
    char line[MAXLINE];
    while (fgets(line, MAXLINE, stdin) ! = NULL && line[0] ! = '\n')
    fputs(line, stdout);
    return 0;
}

Faylga ixtiyoriy murojaat qilish

Ixityoriy kiritish va chiqarish. Hozirgi ko’rib chiqilgan funksiyalar faylga ketma-ket yozish yoki ketma-ket o’qishga imkon beradi xolos. Fayldan o’qib faylga yozishlar doim joriy pozisiyada bo’ladi. Boshlang’ich pozisiya fayl ochilganda aniqlanadi. Faylni "r" va "w" rejimida ochilganda joriy pozisiya ko’rsatkichi faylning birligi baytini ko’rsatadi, "a" rejimida ochilganda, oshish baytini ko’rsatadi. Har bir kiritish-chiqarish amali bajarilganda, ko’rsatkich o’qilgan baytlar soniga qarab yangi pozisiyaga ko’chadi. Faylning ixtiyoriy baytiga murojaat qilish uchun fseek() funksiyasidan foydalanish lozimdir. Bu funksiya quyidagi prototipga ega:

int fseek (faylga ko’rsatkich, oraliq, hisobot boshi ) 

farq long turidagi o’zgaruvchi yoki ifoda bilan beriladi. Hisobot boshi oldin quyidagi konstantalardan biri bilan aniqlanadi.

  • SEEK_SET (qiymati 0)-fayl boshi;
  • SEEK_CUR (qiymati 1)-o’qilayotgan pozisiya;
  • SEEK_END (qiymati 2)-fayl ochish;

fseek() funksiyasi 0 qaytaradi, agar faylda ko’chish bajarilgan bo’lsa, aksincha noldan farqli songa teng bo’ladi.

Ixtiyoriy pozisiyadan fayl boshiga o’tish:

fseek (fp,ol,SEEK_SET)

Ixtiyoriy pozisiyadan fayl boshiga o’tish:

fseek (fp,ol,SEEK_END)

Joriy pozisiyadan bir bayt oldinga yoki orqaga ko’chish uchun fseek (jp,- 1L,SEEK_CUR).

Quyidagi misolda fayldan simvoollar avval to’g’ri tartibda, so’ngra teskari tartibda o’qiladi:

#include <stdio.h>
#include <conio.h>
int main(void)
{
    char file[256];
    char ch;
    FILE *fp;
    long count, last = 0;
    puts("fayl nomini kiriting:\n");
    gets(file);
    if ((fp = fopen(file,"r+")) = = NULL)
    {
        printf("faylni ochib bo'lmadi %s\n", file);
        exit(1);
    }
    while(!feof(fp))
    {
        ch = getc(fp);
        putchar(ch);
        putchar('\n');
        last++;
    }
    for (count = 1L; count < = last; count++)
    {
        fseek(fp, -count, SEEK_END);
        ch = getc(fp);
        putchar(ch);
        putchar('\n');
    }
    fclose(fp);
    getch();
}

fseek funksiyasidan tashqari C tili bibliotekasida pozisiyaga ko’rsatkichlar bilan bog’liq quyidagi funksiyalar mavjud.

  • long ftell (FILE*)-faylda ko’rsatkichning joriy pozisiyasini aniqlash.
  • void rewind (FILE*)-joriy pozisiya ko’rsatkichini fayl boshiga keltirish.

Quyidagi misolda nomi kiritilgan fayl ikkilik rejimda faqat o’qish uchun ochiladi. So’ngra fayl ko’rsatkichi fayl oxiriga keltirilib, ftell funksiyasi yordamida fayl hajmi aniqlanadi. So’ngra rewind funksiyasi yordamida fayl ko’rsatkichi fayl boshiga qaytarilib, siklda simvollar ketma-ket fayldan o’qilib, ekranga chiqariladi.

Dastur matni:

#include <stdio.h>
#include <conio.h>
void main()
{
    char file[256];
    char ch;
    FILE *fp;
    long count, last;
    puts("fayl nomini kiriting:\n");
    gets(file);
    if ((fp = fopen(file,"rb")) = = NULL)
    {
        printf("faylni ochib bo'lmadi %s\n", file);
        exit(1);
    }
    fseek(fp, 0L, SEEK_END);
    last = ftell(fp);
    rewind(fp);
    for (count = 1L; count < = last; count++)
    {
        ch = getc(fp);
        putchar(ch);
        putchar('\n');
    }
    fclose(fp);
    getch();
}

Keyingi misolda nomi kiritilgan fayl simvollari oxiridan boshiga qarab o’qiladi:

#include <stdio.h>
#include <conio.h>
int main(void)
{
    char file[256];
    char ch;
    FILE *fp;
    long count, last;
    puts("fayl nomini kiriting:\n");
    gets(file);
    if ((fp = fopen(file,"rb")) = = NULL)
    {
        printf("faylni ochib bo'lmadi %s\n", file);
        exit(1);
    }
    fseek(fp, 0L, SEEK_END);
    last = ftell(fp);
    for (count = 1L; count < = last; count++)
    {
        fseek(fp, -count, SEEK_END);
        ch = getc(fp);
        putchar(ch);
        putchar('\n');
    }
    fclose(fp);
    getch();
}

Murakkab ma’lumotlarni o’qish va yozish. Murakkab ma’lumotlarni kiritish va chiqarish fread() va fwrite() funksiyalari orqali amalga oshiriladi. Bu funksiyalar prototiplari quyidagi ko’rinishga ega:

size_t fread(void * ptr, size_t size, size_t nmemb, FILE * fp);
size_t fwrite(const void * ptr, size_t size, size_t nmemb, FILE *fp);

Ikkala funksiya butun o’qilgan yoki yozilgan baytlar sonini qaytaradi. fread funksiyasi fp fayl ko’rsatkichi bilan ochilgan fayldan nmemb sonli size parametrida ko’rsatilgan mikdordagi baytlarni o’qib, ptr ko’rsatkichi orqali ko’rsatilgan buferga yozadi. O’qish fayldagi joriy pozisiyadan boshlanadi. Masalan fayldan 10 ta double turidagi sonni o’qib, massivga yozish:

double earnings[10];
fread(earnings, sizeof (double), 10, fp);

fwrite() funksiyasi fp fayl ko’rsatkichi bilan ochilgan faylga nmemb sonli size parametrida ko’rsatilgan mikdordagi baytlarni, ptr ko’rsatkichi orqali ko’rsatilgan buferdan yozadi. Yozish fayldagi joriy pozisiyadan boshlanadi. Masalan faylga 10 ta double turidagi sonni massivdan yozish:

double earnings[10];
fwrite(earnings, sizeof (double), 10, fp);

Faylga 256 bayt ma’lumot yozish:

char buffer[256]; fwrite(buffer, 256, 1, fp);

Quyida struktura turidagi massivni faylga yozish ko’rsatilgan:

#include <stdio.h>
#include <conio.h>
typedef struct
{
    char name[64];
    int age;
    int salary;
}
employee;
int main(void)
{
    int i;
    char file[256];
    FILE* fp;
    employee ww[3] = {{"AA",1,1},{"BB",2,2},{"CC",3,3.0}};
    puts("fayl nomini kiriting:\n");
    gets(file);
    if ((fp = fopen(file,"wb")) = = NULL)
    {
        printf("faylni ochib bo'lmadi %s\n", file);
        exit(1);
    }
    fwrite(&ww[0],sizeof(employee),3,fp);
    fclose(fp);
    getch();
}

Quyida struktura turidagi massivni fayldan o’qish ko’rsatilgan:

#include <stdio.h>
#include <conio.h>
typedef struct
{
    char name[64];
    int age;
    int salary;
}
employee;
int main(void)
{
    int i;
    char file[256];
    FILE* fp;
    employee ww[3];
    puts("fayl nomini kiriting:\n");
    gets(file);
    if ((fp = fopen(file,"rb")) = = NULL)
    {
        printf("faylni ochib bo'lmadi %s\n", file);
        exit(1);
    }
    fread(&ww[0],sizeof(employee),3,fp);
    for(i = 0;i<3; i++)
    printf("\n %s %d %f",ww[i].name,ww[i].age,ww[i].salary);
    fclose(fp);
    getch();
}

Quyi darajadagi kiritish va chiqarish. Quyi darajadagi kiritish va chiqarish funsiyalari operasion tizim imkoniyatlaridan to’g’ridan to’g’ri foydalanishga imkon beradi. Bu holda buferlash va formatlash bajarilmaydi. Faylni quyi darajadagi ochishda fayl bilan fayl (oqim) ko’rsatkichi emas, deskriptor bog’lanadi. Fayl deskriptori fayl ochilganligi to’g’risidagi ma’lumotni operasion tizim ichki jadvallariga joylashtiruvini belgilovchi butun sondir. Quyi darajadagi funksiyalar dasturga stdio.h bibliotekasini qo’shishni talab qilmaydi. Lekin bu biblioteka fayllar bilan ishlashda foydali bo’lgan ba’zi konstantalar (misol uchun fayl yakuni belgisi EOF) tarifini o’z ichiga oladi. Bu konstantalardan foydalanganda stdio.h dasturga qo’shilishi zarurdir.

Fayllarni ochish va yopish. Fayllarni quyi darajada ochish uchun open() funksiyasidan foydalaniladi:

int fd = open (fayl nomi, bayroqlar, murojaat.)
  • fd – fayl deskriptori,
  • fayl nomi – simvollar massiviga ko’rsatkichdir.

2- parametr bayroqlar fayl ochish rejimini belgilovchi ifodadir. Bu ifoda fcntl.h sarlavhali faylda saqlanuvchi konstantalardan biri yoki shu konstantalardan razryadli ‘|’ amali yordamida hosil qilingan bo’lishi mumkin.

Konstantalar ro’yhati:

  • O_APPEND - Faylni oxiriga yozuv qo’shish uchun ochish;
  • O_BINARY - Faylni bitli (ikkilik)binar rejimda ochish;
  • O_CREAT - Yangi fayl yaratish va ochish;

O_EXCL agar O_CREAT bilan birga ko’rsatilgan bo’lsa va yaratilmoqchi bo’lgan fayl mavjud bo’lsa faylni ochish funksiyasi xatolik bilan tugaydi. Mavjud faylni o’chib ketmaslikdan saqlaydi.

  • O_RDONLY - Faylni faqat o’qish uchun ochish;
  • O_RDWR - Faylni o’qish va yozish uchun ochish;
  • O_TEXT - Faylni tekstli rejimda ochish;
  • O_TRUNK - Mavjud faylni ochish va bor ma’lumotni o’chirish;

Fayl ochilish rejimi albatta ko’rsatilgan bo’lishi shart. 3-parametr murojaat huquqlari faqat faylni O_CREAT ochish rejimida ya’ni yangi fayl yaratishda foydalaniladi. MS DOS va MS WINDOWS operasion tizimlarida murojaat huquqlari parametrlarini berish uchun quyidagi konstantalardan foydalaniladi.

  • S_IWRITE - Faylga yozishga ruxsat berish;
  • S_IREAD - Fayldan o’qishga ruxsat berish;
  • S_IREAD\S_WRITE - O’qish va yozishga ruxsat berish;

Ko’rsatilgan konstantalar sys katalogida joylashgan stat.h sarlavhali faylda saqlanadi. Bu faylni qo’shish #include <sys\stade.h> direktivasi orqali amalga oshiriladi. Agar murojaat huquqi parametri ko’rsatilmagan bo’lsa faqat fayldan o’qishga ruxsat beriladi. UNIX operasion tizimida murojaat huquqlari 3 xil foydalanuvchilar uchun ko’rsatiladi:

  1. Fayl egasi;
  2. Foydalanuvchilar guruhi a’zosi;
  3. Boshqa foydalanuvchilar.

Foydalanuvchilar huquqlari quyidagi simvollar orqali ko’rsatiladi:

R- fayldan o’qish ruxsat berilgan. W- faylga yozish ruxsat berilgan. X- fayllarni bajarish ruxsat berilgan. Agar biror murojaat huquqi berilmagan bo’lsa, o’rniga `-` belgisi qo’yiladi. Agar fayl egasiga hamma huquqlar, foydalanuvchi guruxi a’zolariga o’qish va bajarish, boshqa foydalanuvchilarga faqat bajarish huquqi berilgan bo’lsa, murojaat qatorini quyidagicha yozish mumkin rwxr-x—x. har bir `-` simvol o’rniga 0 raqami, aks holda 1 raqami qo’yilib hosil bo’lgan sondagi o’ng tomondan boshlab har bir uch raqamini sakkizlik son sifatida yozilsa, murojaat huquqini belgilovchi sakkizlik butun son hosil bo’ladi. Yuqorida hosil qilingan rwxr-x—x qatori ikkilik 111101001 nihoyat sakkizlik 0751 son shaklida yozilib open() funksiyasida murojaat huquqi parametri sifatida ko’rsatiladi. Faylni ochishga misollar:

  1. Faylni o’qish uchun ochish: fd = open ( “ t.txt “, O_RDONLY)
  2. Faylni o’qish va yozish uchun ochish: fd = open(“ t.txt “, O_RDWR)
  3. Faylni yangi ma’lumotlar yozish uchun ochish: fd = open(“ new.txt “,O_WRONLY |O_Creat| O_TRUNK, 0600)

Faylni ochishda kelib chiqadigan xato turini aniqlash uchun errno.h sarlavhali faylda saqlanuvchi errno o’zgaruvchisi xizmat qiladi. Agar bu o’zgaruvchi qiymati shu sarlavhali faylda saqlanuvchi EEXIST konstantasiga teng bo’lsa ochilayotgan fayl mavjudligini bildiradi. sopen() funksiyasi bitta faylga bir necha dasturlardan murojaat qilish imkonini beradi. Albatta dasturlar faylga faqat o’qish rejimida murojaat qilishi mumkin. Faylni ochish uchun yana creat() funksiyasi mavjud bo’lib quyidagi open() funksiyasini chaqirishga mos keladi.

open( fayl nomi, O_CREAT |O_TRUNK| O_WRONLY); 

bu funksiya yangi fayl yaratadi va yozish uchun ochadi. Quyi darajada fayllarni yopish uchun close() funksiyasidan foydalanish lozim. Bu funksiya ko’rinishi quyidagichadir:

int close (fayl deskriptori)

Funksiya muvaffaqiyatli bajarilganda 0 qaytaradi. Xato bo’lganda – 1.

Ma’lumotlarni o’qish va yozish.

Quyi darajada ma’lumotlarni kiritish va chiqarish read() va write() funksiyalari orqali amalga oshiriladi. Bu funksiyalar prototiplari quyidagi ko’rinishga ega:

int read (int fd, char * buffer; unrigned int count)
int write (int fd, char * buffer; unsiqned int count)

Ikkala funksiya butun o’qilgan yoki yozilgan baytlar sonini qaytaradi. read funksiyasi fd deskriptori bilan ochilgan fayldan count parametrida ko’rsatilgan mikdordagi baytlarni o’qib, buffer ko’rsatkichi orqali ko’rsatilgan bufferga yozadi. Fayl oxiriga yetganda read() funksyasi 0 qiymat qaytaradi. Fayldan o’qishda xatolik kelib chiqsa -1 qiymat qaytaradi. O’qish fayldagi joriy pozisiyadan boshlanadi. Agar fayl matnli rejimda ochilsa CR va LF simvollari `\n` simvoliga o’zgartiriladi. Yozish write() funksiyasi fd deskriptori bilan ochilgan faylga buffer ko’rsatkichi orqali ko’rsatilgan bufferdan count parametri orqali ko’rsatilgan miqdordagi baytlarni yozib qo’yadi. Yozuv joriy pozisiyadan boshlanadi. Agar fayl matnli rejimda ochilgan bo’lsa `\n` simvolini CR va LF simvollar sifatida yoziladi. Agar yozishda xatolik kelib chiqsa, write() funksiyasi -1 qiymat qaytaradi. Xatoni aniqlash errno global o’zgaruvchisi bo’lsa errno.h sarlavhali faylda ko’rsatilgan quyidagi konstantalar biriga teng bo’ladi.

  • EACCES – fayl yozuvdan himoyalangan;
  • ENOSPC – tashqi qurilmada bo’sh joy qolmagan;
  • EBADF – noto’g’ri fayl deskriptori;

Bu funksiyalar io.h sarlavhali faylda joylashgandir. Quyida bir fayldan ikkinchisiga nusxa olish dasturini ko’rib chiqamiz:

#include <stdio.h>
#include <fcnfl.h>
#include <io.h>
int main(int argc, char *argv[ ] )
{
    int fdin, fdout; /*Fayllar deskriptorlari */
    int n; /* O’qilgan baytlar soni */
    char buff[BUFSIZ];
    if (argc ! = 3)
    { 
        printf (“Dastur chaqirish formati: ”);
        printf (“\n %s birinchi_fayl ikkinchi_fayl ”, argv[0]); 
        return 1;
    } 
    if ((fdin = open(argv[1],O_RDONLY)) = = -1)
    { 
        perror (argv[1]);
        return 1;
    }
    if ((fdout = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC)) = = -1)
    {
        perror (argv[2]);
        return 1;
    }
/* fayllar ochilgan */
while ((n = read(fdin, buff, BUFSIZ))>0write (fdout, buff, n );
return 0;
} /* dastur oxiri */

BUFSIZ konstantasi stdio.h sarlavhali faylda aniqlangan bo’lib MS DOS  uchun 512 bayt ga teng.

Faylga ixtiyoriy murojaat. Quyi darajada fayllarni ixtiyoriy tartibda o’qish mumkin. Buning uchun lseek() funksiyasidan foydalanish lozim. Bu funksiya prototipi quyidagi ko’rinishga ega:

long lseek (int fd, long offset, int origin);

Bu funksiya fd deskriptori bilan bog’liq fayldagi joriy pozisiyani uchinchi parametr (origen) orqali nuqtaga nisbatan ikkinchi parametr (offset) qadamga ko’taradi. Boshlang’ich nuqta MS DOS da io.h yoki UNIX da unistd.h sarlavhali fayllarda aniqlangan konstantalar orqali aniqlanadi: 

  • SEEK_SET - (0 qiymatga ega) fayl boshi;
  • SEEK_CUR - (1 qiymatga ega) joriy pozisiya;
  • SEEK_END - (2 qiymatga ega) fayl oxiri.

Ko’chish davomida xato kelib chiqsa xato kodi errno global o’zgaruvchisiga yoziladi. Faylda joriy pozisiyani aniqlash uchun tell() funksiyasidan foydalaniladi:

Bu funksiya prototipi:

long tell (int fd);

Joriy pozisiyani fayl boshiga keltirish:

lseek (fd, oh, SEEK_SET);

Joriy pozisiyani fayl oxiriga keltirish:

lseek (fd, oh, SEEK_END);

Misol:

#include <sys\stat.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
int main(void)
{
    int handle;
    char msg[] = "Uzbekdevs";
    char ch; 
    handle = open("TEST.$$$", O_CREAT | O_RDWR, S_IREAD | S_IWRITE);
    write(handle, msg, strlen(msg));
    lseek(handle, 0L, SEEK_SET);
    do
    {
        read(handle, &ch, 1);
        printf("%c", ch);
    } 
    while (!eof(handle));
    close(handle);
    return 0;
}