logo

Įvesties-išvesties sistemos skambučiai C | Kurti, atidaryti, uždaryti, skaityti, rašyti

Sistemos skambučiai yra iškvietimai, kuriuos programa atlieka sistemos branduoliui, kad teiktų paslaugas, prie kurių programa neturi tiesioginės prieigos. Pavyzdžiui, suteikti prieigą prie įvesties ir išvesties įrenginių, tokių kaip monitoriai ir klaviatūros. Galime naudoti įvairias C programavimo kalboje pateiktas funkcijas įvesties/išvesties sistemos skambučiams, tokiems kaip kurti, atidaryti, skaityti, rašyti ir kt.

Prieš pereidami prie I/O sistemos skambučių, turime žinoti keletą svarbių terminų.



Svarbi terminija

Kas yra failo aprašas?

Failo aprašas yra sveikasis skaičius, unikaliai identifikuojantis atidarytą proceso failą.

Failo deskriptorių lentelė: failas deskriptorių lentelė yra sveikųjų skaičių masyvo indeksų rinkinys, kuris yra failų deskriptoriai, kurių elementai yra rodyklės į failų lentelės įrašus. Kiekvienam procesui operacinėje sistemoje pateikiama viena unikali failų deskriptorių lentelė.



Failų lentelės įrašas: Failų lentelės įrašai yra atviro failo pakaitalas atmintyje, kuri sukuriama apdorojant užklausą atidaryti failą ir šie įrašai palaiko failo padėtį.

Failų lentelės įrašas C

Standartiniai failų aprašai : Kai kuris nors procesas prasideda, tada to proceso failų deskriptorių lentelės fd (failo deskriptorius) 0, 1, 2 atsidaro automatiškai, (pagal numatytuosius nustatymus) kiekvienas iš šių 3 fd nurodo failų lentelės įrašą, skirtą failui pavadinimu /dev/tty



/dev/tty : terminalo pakaitalas atmintyje.

Terminalas : kombinuotas klaviatūros/vaizdo ekranas.

Standartiniai failų aprašai

Skaityti iš stdin => skaityti iš fd 0 : Kai rašome bet kurį simbolį iš klaviatūros, jis nuskaitomas nuo stdin iki fd 0 ir išsaugomas faile pavadinimu /dev/tty.
Rašykite į stdout => rašykite į fd 1 : Kai matome bet kokią išvestį į vaizdo ekraną, ji yra iš failo pavadinimu /dev/tty ir įrašoma į stdout ekrane per fd 1.
Rašykite į stderr => rašykite į fd 2 : Vaizdo įrašo ekrane matome bet kokią klaidą, ji taip pat iš to failo rašoma į stderr ekrane per fd 2.

Įvesties/išvesties sistemos skambučiai

Iš esmės iš viso yra 5 I/O sistemos iškvietimų tipai:

1. C sukurti

Funkcija create() naudojama kuriant naują tuščią failą C. Galime nurodyti failo, kurį norime sukurti, leidimą ir pavadinimą naudodami funkciją create(). Jis apibrėžiamas viduje antraštės failas ir vėliavėlės, kurios perduodamos kaip argumentai, yra apibrėžtos viduje antraštės failą.

Create() sintaksė C

int   create  (char *  filename  , mode_t   mode  );>

Parametras

  • failo pavadinimas: failo, kurį norite sukurti, pavadinimą
  • režimas: nurodo naujo failo teises.

Grąžinimo vertė

  • grąžinti pirmąjį nepanaudotą failo deskriptorių (paprastai 3 pirmą kartą kuriant naudojimo procesą, nes 0, 1, 2 fd yra rezervuoti)
  • grąžinti -1, kai klaida

Kaip C create() veikia OS

  • Sukurkite naują tuščią failą diske.
  • Sukurkite failų lentelės įrašą.
  • Pirmąjį nenaudojamą failo aprašą nustatykite taip, kad jis nurodytų failų lentelės įrašą.
  • Naudojamas grąžinimo failo deskriptorius, -1, jei nepavyko.

2. C atidarytas

Funkcija open() C yra naudojama norint atidaryti failą skaitymui, rašymui arba abiem. Jis taip pat gali sukurti failą, jei jo nėra. Jis apibrėžiamas viduje antraštės failas ir vėliavėlės, kurios perduodamos kaip argumentai, yra apibrėžtos viduje antraštės failą.

Open() sintaksė C

int   open   (const char*   Path  , int   flags  );>

Parametrai

  • Kelias: Kelias į failą, kurį norime atidaryti.
    • Naudoti absoliutus kelias pradedant nuo / kai esate ne dirba tame pačiame kataloge kaip C šaltinio failas.
    • Naudokite santykinis kelias kuris yra tik failo pavadinimas su plėtiniu, kai esate dirba tame pačiame kataloge kaip C šaltinio failas.
  • vėliavėlės: Jis naudojamas norint nurodyti, kaip norite atidaryti failą. Galime naudoti šias vėliavėles.

Vėliavos

apibūdinimas

O_DONLY Failas atidaromas tik skaitymo režimu.
O_WRONLY Failas atidaromas tik rašymo režimu.
O_RDWR Atidaro failą skaitymo ir rašymo režimu.
O_CREATE Sukurkite failą, jei jo nėra.
O_EXCL Neleiskite kurti, jei jis jau egzistuoja.
O_ PRIDĖTI Atidaro failą ir perkelia žymeklį į turinio pabaigą.
O_ASYNC Įjungti įvesties ir išvesties valdymą signalu.
O_CLOEXEC Atidarytame faile įgalinkite uždarymo-exec režimą.
O_NONBLOCK Išjungia atidaryto failo blokavimą.
O_TMPFILE Nurodytu keliu sukurkite bevardį laikinąjį failą.

Kaip C open() veikia OS

  • Raskite diske esantį failą.
  • Sukurkite failų lentelės įrašą.
  • Pirmąjį nenaudojamą failo aprašą nustatykite taip, kad jis nurodytų failų lentelės įrašą.
  • Naudojamas grąžinimo failo deskriptorius, -1, jei nepavyko.

C open() pavyzdys

C




// C program to illustrate> // open system call> #include> #include> #include> #include> extern> int> errno>;> int> main()> {> >// if file does not have in directory> >// then file foo.txt is created.> >int> fd = open(>'foo.txt'>, O_RDONLY | O_CREAT);> >printf>(>'fd = %d '>, fd);> >if> (fd == -1) {> >// print which type of error have in a code> >printf>(>'Error Number % d '>,>errno>);> >// print program detail 'Success or failure'> >perror>(>'Program'>);> >}> >return> 0;> }>

>

>

Išvestis

fd = 3>

3. C uždaryti

Funkcija close() programoje C praneša operacinei sistemai, kad baigėte su failo deskriptoriumi, ir uždaro failo deskriptoriaus nurodytą failą. Jis apibrėžiamas viduje antraštės failą.

Uždaryti () sintaksė C

int close(int fd);>

Parametras

  • fd: F ile failo, kurį norite uždaryti, deskriptorius.

Grąžinimo vertė

  • 0 apie sėkmę.
  • -1 dėl klaidos.

Kaip C close() veikia OS

  • Sunaikinti failų lentelės įrašą, nurodytą failo deskriptorių lentelės elementu fd
    – Kol joks kitas procesas į tai nerodo!
  • Nustatyti failo deskriptorių lentelės elementą fd į NULL

1 pavyzdys: close() C

C




// C program to illustrate close system Call> #include> #include> #include> int> main()> {> >int> fd1 = open(>'foo.txt'>, O_RDONLY);> >if> (fd1 <0) {> >perror>(>'c1'>);> >exit>(1);> >}> >printf>(>'opened the fd = % d '>, fd1);> >// Using close system Call> >if> (close(fd1) <0) {> >perror>(>'c1'>);> >exit>(1);> >}> >printf>(>'closed the fd. '>);> }>

>

>

Išvestis

opened the fd = 3 closed the fd.>

2 pavyzdys:

C




// C program to illustrate close system Call> #include> #include> int> main()> {> >// assume that foo.txt is already created> >int> fd1 = open(>'foo.txt'>, O_RDONLY, 0);> >close(fd1);> > >// assume that baz.tzt is already created> >int> fd2 = open(>'baz.txt'>, O_RDONLY, 0);> > >printf>(>'fd2 = % d '>, fd2);> >exit>(0);> }>

>

>

Išvestis

fd2 = 3>

Čia šiame kode grąžinamas pirmasis open(). 3 nes kai sukuriamas pagrindinis procesas, tada fd 0, 1, 2 jau paimti stdin , stdout, ir stderr . Taigi pirmasis nepanaudotas failo aprašas yra 3 failo deskriptorių lentelėje. Po to close() sistemos skambutis yra nemokamas 3 failų deskriptorius ir tada nustatykite 3 failų aprašai kaip nulinis . Taigi, kai iškvietėme antrąjį open(), tada pirmasis nepanaudotas fd taip pat yra 3 . Taigi, šios programos išvestis yra 3 .

4. C skaitymas

Iš failo, kurį nurodo failo aprašas fd, funkcija read() nuskaito nurodytą baitų kiekį cnt įvesties į atminties sritį, pažymėtą buf . Sėkmingas skaitymas () atnaujina failo prieigos laiką. Funkcija read () taip pat apibrėžta antraštės faile.

Skaitymo () sintaksė C

size_t   read   (int   fd  , void*   buf  , size_t   cnt  );>

Parametrai

  • fd: failo, iš kurio turi būti nuskaitomi duomenys, deskriptorius.
  • buf: buferis duomenims nuskaityti
  • cnt: buferio ilgis

Grąžinimo vertė

  • return Sėkmingai nuskaitytų baitų skaičius
  • grąžinti 0 pasiekus failo pabaigą
  • grąžinti -1 klaidos atveju
  • grąžinimas -1 signalo pertraukimo atveju

Svarbūs punktai

  • buf turi nurodyti tinkamą atminties vietą, kurios ilgis ne mažesnis nei nurodytas dydis dėl perpildymo.
  • fd turėtų būti galiojantis failo deskriptorius, grąžintas iš open(), kad būtų atlikta skaitymo operacija, nes jei fd yra NULL, skaitymas turėtų sukelti klaidą.
  • cnt yra prašomas perskaitytų baitų skaičius, o grąžinama vertė yra tikrasis nuskaitytų baitų skaičius. Be to, kartais perskaitytas sistemos iškvietimas turėtų nuskaityti mažiau baitų nei cnt.

Skaitymo () pavyzdys C

C




// C program to illustrate> // read system Call> #include> #include> #include> int> main()> {> >int> fd, sz;> >char>* c = (>char>*)>calloc>(100,>sizeof>(>char>));> >fd = open(>'foo.txt'>, O_RDONLY);> >if> (fd <0) {> >perror>(>'r1'>);> >exit>(1);> >}> >sz = read(fd, c, 10);> >printf>(>'called read(% d, c, 10). returned that'> >' %d bytes were read. '>,> >fd, sz);> >c[sz] =>' '>;> >printf>(>'Those bytes are as follows: % s '>, c);> >return> 0;> }>

>

>

Išvestis

called read(3, c, 10). returned that 10 bytes were read. Those bytes are as follows: 0 0 0 foo.>

Tarkime, kad foobar.txt susideda iš 6 ASCII simbolių foobar. Kokia yra šios programos išvestis?

C




// C program to illustrate> // read system Call> #include> #include> #include> #include> int> main()> {> >char> c;> >int> fd1 = open(>'sample.txt'>, O_RDONLY, 0);> >int> fd2 = open(>'sample.txt'>, O_RDONLY, 0);> >read(fd1, &c, 1);> >read(fd2, &c, 1);> >printf>(>'c = %c '>, c);> >exit>(0);> }>

>

>

Išvestis

c = f>

Deskriptoriai fd1 ir fd2 kiekvienas turi savo atvirą failų lentelės įrašą, todėl kiekvienas deskriptorius turi savo failo poziciją foobar.txt . Taigi, skaitykite iš fd2 skaito pirmąjį baitą foobar.txt , o išvestis yra c = f , ne c = o .

5. C rašyti

Rašo cnt baitus iš buf į failą arba lizdą, susietą su fd. cnt neturėtų būti didesnis nei INT_MAX (apibrėžtas limits.h antraštės faile). Jei cnt yra nulis, write () tiesiog grąžina 0, nemėgindamas jokio kito veiksmo.

Write () taip pat yra apibrėžtas viduje antraštės failą.

Write() sintaksė C

size_t   write   (int   fd  , void*   buf  , size_t   cnt  );>

Parametrai

  • fd: failo aprašas
  • buf: buferis duomenims rašyti.
  • cnt: buferio ilgis.

Grąžinimo vertė

  • grąžina baitų skaičių, parašytų apie sėkmę.
  • grąžinti 0 pasiekus failo pabaigą.
  • grąžinti -1 klaidos atveju.
  • grąžinimas -1 signalo pertrūkiams.

Svarbūs punktai apie C rašymą

  • Failas turi būti atidarytas rašymo operacijoms atlikti
  • buf turi būti bent tokio ilgio, kiek nurodyta cnt, nes jei buf dydis yra mažesnis nei cnt, buf sukels perpildymo sąlygą.
  • cnt yra prašomas įrašyti baitų skaičius, o grąžinama vertė yra tikrasis parašytų baitų skaičius. Tai atsitinka, kai fd turi mažiau rašomų baitų nei cnt.
  • Jei rašymas () nutraukiamas signalo, efektas yra vienas iš šių:
    • Jei write() dar neparašė jokių duomenų, jis grąžina -1 ir nustato errno į EINTR.
    • Jei write () sėkmingai įrašė kai kuriuos duomenis, jis grąžina baitų skaičių, kurį parašė prieš nutraukdamas.

Write() pavyzdys C

C

k artimiausias kaimynas




// C program to illustrate> // write system Call> #include> #include> main()> {> int> sz;> int> fd = open(>'foo.txt'>, O_WRONLY | O_CREAT | O_TRUNC, 0644);> if> (fd <0)> {> >perror>(>'r1'>);> >exit>(1);> }> sz = write(fd,>'hello geeks '>,>strlen>(>'hello geeks '>));> printf>(>'called write(% d, 'hello geeks ', %d).'> >' It returned %d '>, fd,>strlen>(>'hello geeks '>), sz);> close(fd);> }>

>

>

Išvestis

called write(3, 'hello geeks
', 12). it returned 11>

Čia, kai pamatysite faile foo.txt paleidę kodą, gausite a sveiki geikai . Jei faile foo.txt jau yra tam tikro turinio, tada rašymo sistemos iškvietimai perrašo turinį ir visas ankstesnis turinys yra ištrintas ir tik sveiki geikai turinys bus faile.

Pavyzdys: Spausdinkite hello world iš programos nenaudodami jokios printf funkcijos.

C




// C program to illustrate> // I/O system Calls> #include> #include> #include> #include> int> main(>void>)> {> >int> fd[2];> >char> buf1[12] =>'hello world'>;> >char> buf2[12];> >// assume foobar.txt is already created> >fd[0] = open(>'foobar.txt'>, O_RDWR);> >fd[1] = open(>'foobar.txt'>, O_RDWR);> >write(fd[0], buf1,>strlen>(buf1));> >write(1, buf2, read(fd[1], buf2, 12));> >close(fd[0]);> >close(fd[1]);> >return> 0;> }>

>

>

Išvestis

hello world>

Šiame kode buf1 masyvo eilutė Labas pasauli pirmiausia įrašoma į stdin fd[0], tada ši eilutė įrašoma į stdin į buf2 masyvą. Po to įrašykite į buf2 masyvą į stdout ir spausdinkite išvestį Labas pasauli .