Download presentation
Presentation is loading. Please wait.
1
Rad sa datotekama Damir Krstinić
Programiranje za UNIX Rad sa datotekama Damir Krstinić
2
Sadržaj Otvaranje i zatvaranje datoteka
Čitanje i pisanje sadržaja datoteka Dijeljenje datoteka među procesima Programiranje za UNIX 11/29/2018
3
File deskriptori Kernel datoteke referencira preko tzv. file descriptora (nenegativni cjeli broj). Pri otvaranju datoteke program dobiva jedinstveni file descriptor koji koristimo kada želimo u datoteku pisati ili iz nje čitati. Fd. 0 - standardni ulaz Fd. 1 standardni izlaz Fd. 2 standardni izlaz za greške. Programiranje za UNIX 11/29/2018
4
Samo jedna od spomenutih konstanti smije biti navedena!!!
open() #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname, int oflag, … /*, \ mode_t mode */); Vraća file deskriptor, -1 u slučaju greške oflag se dobija kombiniranjem (OR) više konstanti, a mora sadržavati jednu od 3 konstante: O_RDONLY (samo čitanje), O_WRONLY (Samo pisanje), O_RDWR (Čitanje i pisanje) Samo jedna od spomenutih konstanti smije biti navedena!!! Programiranje za UNIX 11/29/2018
5
open() Sljedeće konstante su opcionalne:
O_APPEND Kod svakog pisanja dodaj na kraj datoteke O_CREAT Kreiraj novu datoteku ako ne postoji. Ova opcija zahtijeva treći argument za funkciju, u kojem su navedene ovlasti nad datotekom. O_EXCL Ukoliko je O_CREAT naveden, a datoteka već postoji, funkcija vraća grešku. Test i kreiranje datoteke je tzv. atomska operacija. O_TRUNC ukoliko je datoteka otvorena za pisanje, ili za pisanje i čitanje, sadržaj se briše (dužina datoteke postaje 0). Programiranje za UNIX 11/29/2018
6
open() O_NONBLOCK Ukoliko se radi o specijalnim datotekama (FIFO, block special file, ili character special file) ova opcija postavlja neblokirajući mod za I/O operacije. O_SYNC Za svaki write funkcija čeka dok se ne završi fizičko pisanje. File desc. Koji vrati funkcija open je najniži slobodni file deskriptor Ovo ponašanje neke aplikacije koriste za otvaranje datoteka na standardnom ulazu, izlazu, ili standardnom izlazu za greške. Programiranje za UNIX 11/29/2018
7
creat() Ova funkcija je ekvivalentna sa:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int creat(const char *pathname, mode_t mode); Vraća file deskriptor, -1 u slučaju greške Ova funkcija je ekvivalentna sa: open (pathname, O_WRONLY | O_CREAT | O_TRUNC, mode); creat može otvoriti datoteku samo za pisanje. Programiranje za UNIX 11/29/2018
8
close() #include <unistd.h> int close(int filedes); Vraća 0 ako je sve u redu, -1 u slučaju greške Kad proces (pokrenuti program) završi sa radom, sve otvorene file deskriptore zatvara kernel. Programiranje za UNIX 11/29/2018
9
lseek() lseek eksplicitno pozicionira offset otvorene datoteke
#include <sys/types.h> #include <unistd.h> off_t lseek(int filedes, off_t offset, int whence); Vraća novi položaj (file offset) u datoteci, -1 u slučaju greške lseek eksplicitno pozicionira offset otvorene datoteke Za svaku otvorenu datoteku, kernel pamti trenutni offset. Ukoliko kod otvaranja datoteke nije specificirana O_APPEND opcija, sve operacije pisanja i čitanja datoteke započinju od ove točke. Programiranje za UNIX 11/29/2018
10
lseek() Rezultat funkcije ovisi o vrijednosti parametra whence:
whence=SEEK_SET, offset se postavlja na offset byteova od početka datoteke. whence=SEEK_CUR, offset se postavlja na offset byteova od trenutne pozicije. Offset može biti pozitivan i negativan whence=SEEK_END, offset se postavlja na offset byteova od kraja datoteke. Offset može biti pozitivan i negativan Primjer: Kako lseek vraća novi file offset, pomicanjem offseta za 0 byteova od trenutne pozicije možemo odrediti trnutni file offset: off_t currpos; currpos = lseek(fd, 0, SEEK_CUR); Programiranje za UNIX 11/29/2018
11
U datoteci ostaje ‘rupa’!
Primjer f_hole.c offset postavljamo u odnosu na trenutnu poziciju “First line of text” write(fd) fd lseek(fd,20,SEEK_CUR); fd=creat() offset ‘F’ ‘i’ ‘r’ ‘s’ ‘t’ ... ‘t’ ‘e’ ‘x’ ‘t’ \0 \0 ... \0 ‘F’ ‘i’ ‘r’ ‘s’ ‘t’ ... ‘t’ ‘e’ ‘x’ ‘t’ \0 \0 ... \0 ‘S’ ‘e’ ‘c’ ... write(fd) U datoteci ostaje ‘rupa’! “Second line of text” Programiranje za UNIX 11/29/2018
12
Primjer 2.1 - f_hole.c #include <sys/types.h> int main() {
... int main() { char buf1[]="First line of text"; char buf2[]="Second line of text"; int fd; fd=creat("file.hole", (mode_t)0644); if (fd==-1) perror("creat"); if (write(fd, buf1, strlen(buf1)+1)!=strlen(buf1)+1) perror("write buf1"); if (lseek(fd, 20, SEEK_CUR)==-1) perror("lseek"); if (write(fd, buf2, strlen(buf2)+1)!=strlen(buf2)+1) perror("write buf2"); close(fd); exit(0); } Programiranje za UNIX 11/29/2018
13
Primjer 2.2 - f_strip.c write(fd) fd fd=open() write(fd)
offset postavljamo u odnosu na početak datoteke “First line of text” write(fd) fd lseek(fd,15,SEEK_SET); fd=open() offset ‘F’ ‘i’ ‘r’ ‘s’ ‘t’ ... ‘t’ ‘e’ ‘x’ ‘t’ \0 ‘F’ ‘i’ ‘r’ ‘s’ ‘t’ ... ‘t’ ‘S’ ‘e’ ‘c’ ‘o’ ‘n’ ... ‘t’ ‘e’ ‘x’ ‘t’ \0 write(fd) Pišemo preko Prethodnog sadržaja “Second line of text” Programiranje za UNIX 11/29/2018
14
Primjer 2.2 - f_strip.c #include <sys/types.h> int main() {
... int main() { char buf1[]="First line of text"; char buf2[]="Second line of text"; int fd; fd=open("file.strip",O_WRONLY | O_CREAT | O_TRUNC,(mode_t)0644); if (fd==-1) perror(“open"); if (write(fd, buf1, strlen(buf1)+1)!=strlen(buf1)+1) perror("write buf1"); if (lseek(fd, 15, SEEK_SET)==-1) perror("lseek"); if (write(fd, buf2, strlen(buf2)+1)!=strlen(buf2)+1) perror("write buf2"); close(fd); exit(0); } Programiranje za UNIX 11/29/2018
15
read() #include <unistd.h> ssize_t read(int filedes,void *buff, size_t nbytes); vraća broj pročitanih byteova, 0 za kraj datoteke, -1 u slučaju greške. Čitanje počinje na trenutnom offsetu. Prije povratka iz funkcije offset se povećava za broj pročitanih byteova. Broj pročitanih byteova može biti manji od traženog (nbytes): Detektiran je kraj datoteke Čitanje iz posebnih datoteka (FIFOs, devices, network) Programiranje za UNIX 11/29/2018
16
write() #include <unistd.h> ssize_t write(int filedes, void *buff, size_t nbytes); vraća broj upisanih byteova, -1 u slučaju greške. Pisanje počinje na trenutnom offsetu. Prije povratka iz funkcije offset se povećava za broj upisanih byteova. Ukoliko je kod otvaranja datoteke uključena O_APPEND opcija, offset se prije svakog pisanja postavlja na kraj datoteke. Programiranje za UNIX 11/29/2018
17
write(STDOUT_FILENO);
Primjer f_copy.c Standardni ulaz (automatski otvoren na file deskriptoru 0) Standardni izlaz (automatski otvoren na file dekriptoru 1) fd 0 fd 1 read(STDIN_FILENO); write(STDOUT_FILENO); Programiranje za UNIX 11/29/2018
18
Primjer 2.3 - f_copy.c #include <sys/types.h>
#include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> #include <string.h> #define BUFFSIZE 8192 int main() { int n; char buf[BUFFSIZE]; while((n=read(STDIN_FILENO, buf, BUFFSIZE)) > 0) { if (write(STDOUT_FILENO, buf, n) != n) perror("write"); } if (n<0) perror("read"); exit(0); Programiranje za UNIX 11/29/2018
19
umask() #include <sys/types.h> #include <sys/stat.h> mode_t umask(mode_t cmask); Vraća prethodnu vrijednost maske Funkcija umask postavlja masku za mod kreiranja datoteka za proces i vraća prethodnu vrijednost maske. Svaki put kada proces kreira novu datoteku, svi bitovi (prava pristupa) koji su uključeni u maski isključuju se u pravima pristupa datoteci. Programiranje za UNIX 11/29/2018
20
umask() Argument cmask se formira disjunkcijom (logičko ili - OR) konstanti za prava pristupa datotekama (S_IRUSR, S_IWUSR, S_IXUSR, ...). st_mode mask Značenje S_IRUSR S_IWUSR S_IXUSR user-read user-write user-execute S_IRGRP S_IWGRP S_IXGRP group-read group-write group-execute S_IROTH S_IWOTH S_IXOTH other-read other-write other-execute Programiranje za UNIX 11/29/2018
21
Primjer 2.4 – perm_mask.c #include <sys/types.h>
#include <sys/stat.h> #include <fcntl.h> #include <stdio.h> int main() { umask(0); if (creat("test_foo", S_IRUSR | S_IWUSR | \ S_IRGRP | S_IWGRP | S_IROTH) < 0) perror("creat error for test_foo"); umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (creat("test_bar", S_IRUSR | S_IWUSR | \ perror("creat error for test_bar"); exit(0); } Programiranje za UNIX 11/29/2018
22
Primjer 2.4 – perm_mask.c Program perm_mask.c kreira datoteke sa istim navedenim pravima pristupa, ali sa različitom maskom za mod kreiranja datoteke. Korištenje: /> perm_mask /> ls -l test_bar test_foo -rw dkrst 0 Jan 16 16:23 test_bar -rw-rw-r-- 1 dkrst 0 Jan 16 16:23 test_foo Programiranje za UNIX 11/29/2018
23
I/O strukture podataka
Svaki proces opisan je zapisom u tablici procesa (process table - u kernelu). Između ostalog, svaki zapis ima tablicu otvorenih file descriptora za proces koja sadrži: Pokazivač na slog u tablici datoteka (file table) zastavice (flags) za file descriptor. Zapis u tablici datoteka čine: statusne zastavice za datoteku (read, write, append, itd.) trenutni file offset pokazivač na slog u v-node tablici za datoteku Za svaku otvorenu datoteku (ili uređaj) v-node sadrži informacije o vrsti datoteke i pokazivače na funkcije za rad s datotekom. Ovi podaci se učitavaju u trenutku otvaranja datoteke. Programiranje za UNIX 11/29/2018
24
I/O strukture podataka
v-node table file table v-node information i-node information current file size Process table entry file status flags current file offset fd flags ptr v-node ptr fd 0: fd 1: ... v-node information file status flags i-node information current file size current file offset v-node ptr Datoteke su otvorene Na standardnom ulazu (fd 0) i standardnom izlazu (fd 1) Proces sa dvije otvorene datoteke Programiranje za UNIX 11/29/2018
25
I/O strukture podataka
Za većinu datoteke v-node sadrži i-node za danu datoteku. Na primjer, i-node sadrži informaciju o vlasniku datoteke, veličini, uređaju na kojem se nalazi datoteka i pokazivače na blokove podataka na disku u kojima je zapisan sadržaj datoteke. Programiranje za UNIX 11/29/2018
26
Dijeljenje datoteka Dva procesa dijele istu datoteku P1 P2 ... ...
Process table entry v-node table fd flags ptr file table fd 0: fd 1: fd 2: fd 3: file status flags current file offset v-node information ... v-node ptr P1 i-node information current file size fd 0: fd 1: fd 2: fd 3: file status flags current file offset v-node ptr ... P2 Dva procesa dijele istu datoteku Programiranje za UNIX 11/29/2018
27
Dijeljenje datoteka Svaki proces dobiva slog u tablici datoteka. Datoteka ima samo jedan zapis u v-node tablici. Više file descriptora može pokazivati na isti zapis u tablici datoteka. File descriptor zastavice (process table) primjenjuju se na jedan descriptor unutar procesa, dok se file status zastavice (file table) primjenjuju na sve descriptore u svim procesima koji na taj zapis pokazuju. Djeljenje za čitanje je jednostavno, ali kod višestrukog pisanja mogu nastati problemi. Programiranje za UNIX 11/29/2018
28
Atomske (atomic) operacije
Atomske (atomic) operacije su takve operacije koje se satoje od više koraka, a izvode se na način da se izvrše svi koraci, ili se ne izvršava niti jedan. Vrlo je važno da ne postoji mogućnost da se izvrši samo dio operacije, tj. ne postoji mogućnost da operacija bude prekinuta za vrijeme izvođenja!!! Programiranje za UNIX 11/29/2018
29
Atomske (atomic) operacije
Process A stopped lseek write Process B lseek write stopped stopped Dva procesa pišu u istu datoteku: Proces A postavlja file offset na kraj datoteke Proces A zaustavljen, proces B se izvršava Proces B postavlja file offset na kraj datoteke Proces B piše Proces B zaustavljen, proces A se izvršava Proces A piše (na svoj trenutni offset) Podaci procesa B su prebrisani!!! Podaci procesa A Podaci procesa B Programiranje za UNIX 11/29/2018
30
Atomske (atomic) operacije
U trenutku kada proces A pozicionira file offset na kraj datoteke, kernel ga zaustavlja i aktivira proces B koji piše u istu datoteku. Kada se ponovo aktivira proces A, podaci koje upisuje u datoteku upisuju se preko podataka procesa B. Rješenje je da pozicioniranje offseta i upisivanje u datoteku bude atomska operacija (nije je moguće prekinuti). Ovo se može postići ukoliko pri otvaranju datoteke uključimo O_APPEND zastavicu. U ovom slučaju, pri svakom pozivu write funkcije, kernel u atomskoj operaciji pozicionira offset na kraj datoteke i upisuje podatke. Programiranje za UNIX 11/29/2018
31
dup() i dup2() #include <unistd.h> int dup(int filedes);
int dup2(int filedes, int filedes2); Obje funkcije vraćaju novi file descriptor, ili -1 u slučaju greške dup vraća najniži slobodni descriptor. dup2 vraća descriptor naveden sa filedes2 argumentom. Ukoliko na filedes2 već otvorena neka datoteka, ona se najprije zatvara. Ukoliko je filedes jednak filedes2, dup2 vraća filedes2 bez prethodnog zatvaranja. Novi descriptor dijeli isti zapis u tablici datoteka (file table) sa filedes deskriptorom. Programiranje za UNIX 11/29/2018
32
dup() i dup2() Non atomic: Atomic: close(1); dup2(fd, 1); dup(fd); ...
file table v-node table Process table entry fd flags ptr v-node information fd 0: fd 1: fd 2: fd 3: i-node information current file size file status flags current file offset ... v-node ptr Non atomic: Atomic: close(1); dup2(fd, 1); dup(fd); Programiranje za UNIX 11/29/2018
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.