Ugrás a kezdőlapra

© Mohos Pál

Alacsonyszintű fájlkezelés

Utolsó módosítás: 2014. szeptember 9. kedd   11:04

                                     

IO.H         (Schuszter k. 10.2    fejezet) alacsony szintű file kez.        
STDIO.H  (Schuszter k. 10.2.2 fejezet) magas szintű file kez.

1.1        Általános szöveg

1.1.1          Be-kiviteli fv.ek

·         A pr. Eszközfüggetlen.  (minden be-ki-t filenak tekint Bill, képernyő, rs232, nyomtató, lemez file..).

·         Az adatátvitel egysége: BYTE. , de a C-ben helyette CHAR-t mondanak, mivel char típusú változó létezik.

1.1.2          File pozíció

·         Szám. Hanyadik byte-on vagyunk. (0-val kezd). Abszolút és relatív módon léptethetünk.

·         SEEK_SET=0 eleje;        SEEK_CUR=1 aktuális;        SEEK _END=2 file vége

1.1.3          Text-bináris kezelés

·         Szöveg filek sorvége CR+LF. Történelem.

·         A C-ben csak a CR kód a \n.

·         Ezért, ha szöveg file-nél beolvasásnál levágjuk, kiírásnál betsszük. Bináris filenál nem figyeljük ezeket a karaktereket. Tehát file megnyitáskor a kezelési módot meg kell mondani. Az alapértelmezés (ha nem mondjuk meg) a szöveges.

1.1.4          Alacsony szintű be-kivitel   (io.h fcntl.h) (Schuszter 160.)

A filet egydimenziós karaktertömbnek tekinti. A mutató byteonként lépeget.

·         0= terminál

·         1=képernyő

·         2=hibakimenet (képernyő)

·         3=COM1

·         4=LPT1 (printer)

 

open   close

read   write

lseek  tell

sizeof

Nyit - Zár

OlvasFájlba ír

pozicióra áll, aktuális poz?

 

 

1.1.5          Folyam jellegű (magas szintű) be-ki vitel.

·         saját pufferrel dolgozik ezáltal sok filenel gyorsabb, de több memória kell neki. A saját puffer miatt lehet pl printf() is.

·         Bő a fv választék. (pl formátumozott kiiratás, beolvasás stb.)

·         Fopen, fclose, getc, putc, fprintf, fscanf, fseek, ftell


1.2        Alacsonyszintű file kezelés elmélet

1.2.1          Nyit, pozicionál

int creat (const char *path,
       int amode)

létrehoz, vagy felülír adott módú hozzáf. joggal
S_IWRITE,   S_IREAD,     S_IWRITE | S_IREAD, # include <sys\stat.h>

Siker:   file leíró tömb sorszáma

Hiba:   -1


io.h

int open(const char     *filenev,
       int mode,
       unsigned attrib)

int fh;

fh=open(FNEV, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IWRITE|S_IREAD);

file aktiválás paraméterezve (ir és/vagy olvas) fizikai név èlogikai név

mode: O_RDONLY csak olvasásra,
           O_WRONLY csak írásra,                    O_RDWR írásra, olvasásra,
           O_APPEND minden írás csak hozzáfűzés
           O_CREAT létrehoz, ha nem volt
           O_EXCL   létezik és létrehoz =hiba
           O_TRUNC       töröl (újra ír), ha létezik
           O_BINARY     CR
           O_TEXT    CR+LF

attrib:  ha volt O_CREAT csak akkor kell!
            S_IWRITE
            S_IREAD
            S_IWRITE | S_IREAD
Siker:   file leíró tömb sorszáma

Hiba:  -1

 

long lseek(int file1,
       long offset,
       int origin)

File pozíció állítása.

offset:           ennyi byte-al mozgatjuk (előjelesen) az

origin   -ban közölt pozíciótól
            SEEK_SET    file eleje     0
            SEEK_CUR            aktuális           1
            SEEK_END   file vége    2

Siker:   file pozíció (byte szám a file elejétől)

Hiba:   -1L

 

int close (int file1)

0, ha sikeres a lezárás

io.h

1.2.2          Olvas, ír

int read  (fh ,memória cím,

     hossz byteokban)

len db byte-ot olvas a memóriába a buf cimre.

Siker:   byte szám, 0, ha filevég

Hiba:   -1

io.h

int write (fh ,memória cím,
       hossz byteokban)

write(fh,&f,4);

len db byte-ot ír a memóriábol a buf cimtől

Siker:   byte szám,

Hiba:   -1

 

1.2.3          Tesztelések

int eof   (int file1)

1, ha az aktuális file poz a filevég.
0, ha nincs vége a filenak

io.h

long int  tell (int file1)

Linux alatt nincs ez a függvény! (Csak windows alatt van.)

Siker:   aktuális file pozíció

Hiba:  -1

 

1.3        Alacsonyszintű file kezelés példák

//Mohos Pál alacsony fájlkezelés kidolgozott példaprogramja.

#include <stdlib.h>            // exit() függvény miatt

#include <fcntl.h>             // open(), close(), write(), read() ... miatt

#include <sys/stat.h>          // S_IREAD, S_IWRITE és egyéb módok definiálása található itt

#include <stdio.h>             // SEEK_SET és társainak definiálatlan található itt

#include <io.h>                // Linux alatt nem kell.

#include <string.h>

 

#define FN "1.txt"

#define BHOSSZ 257           //256. bájt után a stringzárónak 1 bájt hely kell

int main() {

    int fh,a,szlo;             //fn=fájl puffer sorszám

    char s[]="AB\nD", b[BHOSSZ];

//******************************Fájlba ír *************************

    fh=open(FN,O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE); //Fájl nyitás

    a=write(fh,s,strlen(s));   //s string fájlba (pufferbe) tétele.

    close(fh);                 //Puffer ürítése a fájlba.

 

//******************************Fájlból kiíratása karakterenként***********

    printf("\n");

    fh=open(FN,O_RDONLY|O_BINARY);      //mutató a fájl elejére áll.

    while(!eof(fh))            //karakterenként olvas-ír. Ez lassú!

        {read(fh,&a,1); putchar(a); };

//---------------------------------------Fájlból kiíratása tömbönként-------------

    printf("\n");lseek(fh,0,0);//mutató a fájl elejére áll.

    while(!eof(fh))

        {a=read(fh,b,BHOSSZ-1); b[a]=0; puts(b);}

    close(fh);

 

//******************************Fájl végére írja a fájl hosszát int típusban lseek()***********

    fh=open(FN,O_RDWR|O_BINARY);a=0;//Fontos a O_BINARY. Miért?

    a=lseek(fh,0,2);a=a+sizeof(a);  //lseek az aktuális fájlmutatót adja az a-nak.

    szlo=write(fh,&a,sizeof(a));

    close(fh);

 

    //----------------------------------tell()--------------------

    fh=open(FN,O_RDWR|O_APPEND|O_BINARY);a=0;

    lseek(fh,0,2);a=tell(fh);a=a+sizeof(a);  // a fájl végére állok. Ott kiolvasom a mutató értékét.

    szlo=write(fh,&a,sizeof(a));   

    //------------------------------  számlálás egyenként.

    szlo=0; lseek(fh,0,0);

    while(!eof(fh)){read(fh,&a,1);szlo++;}

    szlo+=sizeof(szlo); lseek(fh,0,0);  //Az O_APPEND miatt nem lehet mozgatni a mutatót írásnál.

    write(fh,&szlo,sizeof(szlo));//Csak HOZZÁFüZHETEK!lseek itt nem kell!

    close(fh);

//**********************************-----------------------------------------

    return 0;

}

1.4        Wiki példák:

(a tell() miatt csak windows alatt futnak!)

1.4.1          1

Nyissa meg, illetve hozza létre a pelda.txt nevü fájlt az aktuális könyvtárban. Az open visszatérési értékéből állapítsa meg, hogy sikeres volt-e a megnyitás, ezt írja ki a képernyőre.

#include <stdlib.h>            // exit() fuggveny miatt
#include <fcntl.h>             // open(),close(),write(),read() ... miatt
#include <sys/stat.h>          // S_IREAD, S_IWRITE es egyeb modok definialsa talalhato itt
#include <stdio.h>             // SEEK_SET es tarsainak definialsa talalhato itt
#include <io.h>
 
int main(void)
{
int fh;
int a;   // olvasott vagy irt karakterek szama
char c;
fh=open("pelda.txt",O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
if(fh==-1) // baj van
  {
  printf("Nem sikerult a file megnyitasa!\n");
  exit(1);               // kilepunk a programbol 1 ertekkel jelezzuk h hiba van;
  }
printf("Megnyilt a file.");
 
close(fh);
return 0;
}

1.4.2          2

Nyissa meg a pelda.txt fájlt. Írja bele, hogy "csoki", majd olvasson ki karaktereket a következő pozíciókról:

  • első karakter
  • utolsó karakter
  • harmadik karakter
  • az előző +2 karakter
#include <stdlib.h>            // exit() fuggveny miatt
#include <fcntl.h>             // open(),close(),write(),read() ... miatt
#include <sys/stat.h>  // S_IREAD, S_IWRITE es egyeb modok definialsa talalhato itt
#include <stdio.h>             // SEEK_SET es tarsainak definialsa talalhato itt
#include <io.h>
 
 
int main(void)
{
int fh;
int a;   // olvasott vagy irt karakterek szama
char c;
fh=open("pelda.txt",O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
if(fh==-1) // baj van
  {
  printf("Nem sikerult a file megnyitasa!\n");
  exit(1);       // kilepunk a programbol 1 ertekkel jelezzuk h hiba van;
  }
printf("Megnyilt a file.");
 
a=write(fh,"etcsoki",5);
printf("Ennyit karaktert irtam a fileba: %i\n",a);
printf("Aktualis fajlpozicio: %i\n",tell(fh));
printf("A fajl elejere pozicionalas\n",tell(fh));
lseek(fh,0,SEEK_SET);
printf("Aktualis fajlpozicio: %i\n",tell(fh));
a=read(fh,&c,1);
printf("Ezt olvastam az elejerol: %c\n",c);
printf("Aktualis fajlpozicio: %i\n",tell(fh)); 
printf("A fajl vege -1-re pozicionalas\n",tell(fh));
lseek(fh,-1,SEEK_END);
printf("Aktualis fajlpozicio: %i\n",tell(fh));
a=read(fh,&c,1);
printf("Ezt olvastam a vegerol: %c\n",c);
printf("Aktualis fajlpozicio: %i\n",tell(fh)); 
printf("A fajl elejetol +2-re pozicionalas\n",tell(fh));
lseek(fh,2,SEEK_SET);
printf("Aktualis fajlpozicio: %i\n",tell(fh));
a=read(fh,&c,1);
printf("Ezt olvastam az eleje +2 rol: %c\n",c);
printf("Aktualis fajlpozicio: %i\n",tell(fh)); 
printf("A fajl aktualis +1-re pozicionalas\n",tell(fh));
lseek(fh,1,SEEK_CUR);
printf("Aktualis fajlpozicio: %i\n",tell(fh));
a=read(fh,&c,1);
printf("Ezt olvastam a jelenlegi +2 poziciorol: %c\n",c);
printf("Aktualis fajlpozicio: %i\n",tell(fh)); 
 
close(fh);
return 0;
}

1.4.3          3

Nyissa meg a pelda.txt fájlt. Írja bele 10x, hogy "lali", majd:

pozicionáljon a fájl elejére és irassa ki karakternként a fájl tartalmát a képernyőre azt, hogy a fájl vágáre ért-e azt az eof() függvénnyel vizsgálja

 

#include <stdlib.h>            // exit() fuggveny miatt
#include <fcntl.h>             // open(),close(),write(),read() ... miatt
#include <sys/stat.h>  // S_IREAD, S_IWRITE es egyeb modok definialsa talalhato itt
#include <stdio.h>             // SEEK_SET es tarsainak definialsa talalhato itt
#include <io.h>
 
 
int main(void)
{
int fh;
int a,i; // olvasott vagy irt karakterek szama
char c, str[]="lali";
fh=open("pelda.txt",O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
if(fh==-1) // baj van
   {
   printf("Nem sikerult a file megnyitasa!\n");
   exit(1);      // kilepunk a programbol 1 ertekkel jelezzuk h hiba van;
   }
printf("Megnyilt a file.");
 
for(i=0;i<10;i++)
   {
   write(fh,str,sizeof(str)-1); // -1  kell mert nem akarunk sztringzáró karaktert beirni, lehetne hasznalni strlen-t is
   }
 
lseek(fh,0,SEEK_SET); // visszapozicinalok a file elejere
 
while(1)
   {
   i=read(fh,&c,1);
   if(i<=0) break;
   printf("%c",c);
   }
 
close(fh);
return 0;
}

1.4.4          4.

Nyissa meg a pelda.txt fájlt. Írja bele 10x, hogy "lali", majd:

pozicionáljon a fájl elejére és cserélje ki az 'i' betüket 'a' betükre.

#include <stdlib.h>            // exit() fuggveny miatt
#include <fcntl.h>             // open(),close(),write(),read() ... miatt
#include <sys/stat.h>  // S_IREAD, S_IWRITE es egyeb modok definialsa talalhato itt
#include <stdio.h>             // SEEK_SET es tarsainak definialsa talalhato itt
#include <io.h>
 
int main(void)
{
   int fh;
   int a,i;    // olvasott vagy irt karakterek szama
   char c, d, str[]="lali";
   fh=open("pelda.txt",O_RDWR|O_CREAT, S_IREAD|S_IWRITE);
   if(fh==-1) // baj van
        {
        printf("Nem sikerult a file megnyitasa!\n");
        exit(1);       // kilepunk a programbol 1 ertekkel jelezzuk h hiba van;
        }
   printf("Megnyilt a file.");
 
   for(i=0;i<10;i++)
        {
        write(fh,str,sizeof(str)-1); // -1  kell mert nem akarunk sztringzáró karaktert beirni, lehetne hasznalni strlen-t is
}
 
   lseek(fh,0,SEEK_SET); // visszapozicinalok a file elejere
 
   d='a'; //erre a karakterre cseréljük ki az 'i'-t
 
  while(1)
       {
       i=read(fh,&c,1);
       if(i<=0) break;
       if(c=='i')
          {
          lseek(fh,-1,SEEK_CUR);
          write(fh,&d,1); // figyelem: a d változó tartalmazza a csere karaktert
          }
       }
 
  lseek(fh,0,SEEK_SET); // visszapozicinalok a file elejere
 
  while(1)
      {
      i=read(fh,&c,1);
      if(i<=0) break;
      printf("%c",c);
      }
  close(fh);
  return 0;
  }