Programowanie C

Funkcja odczytu POSIX w programowaniu C

Funkcja odczytu POSIX w programowaniu C
W tradycyjnych systemach operacyjnych zgodnych z POSIX, aby uzyskać informacje z dokumentu zawartego w systemie plików, program używał wywołania systemowego read. Deskryptor dokumentu, do którego zwykle uzyskuje się dostęp z poprzedniego wywołania otwarcia, jest zdefiniowany przez plik. To wywołanie systemowe read odczytuje z dokumentu informacje w bajtach i liczbę całkowitą, którą osoba wywołująca określa, a następnie zapisuje ją w buforze udostępnionym przez mechanizm wywołujący.

Definicja funkcji

Zanim zdefiniujesz funkcję read w swoim kodzie, musisz dołączyć kilka wymaganych pakietów.

#zawierać

Oto jak definiujesz funkcję odczytu POSIX:

>> ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
>> ssize_t read(int fd, void *buf, size_t nbajtów);

Z wywołania metody read można pobrać trzy argumenty parametrów:

wewn fd: Deskryptor pliku, z którego mają być odczytane informacje. Moglibyśmy użyć deskryptora pliku uzyskanego przez otwarte wywołanie systemowe lub po prostu użyć 0, 1 lub 2, odnosząc się odpowiednio do typowego wejścia, regularnego wyjścia lub zwykłego błędu.

Unieważnij *buf: Bufor lub tablica znaków, w której powinny być zapisywane i przechowywane odczytane dane.

Rozmiar_t nbajtów: Liczba bajtów, które należało odczytać z dokumentu przed obcięciem. Wszystkie informacje mogą być przechowywane w buforze, jeśli odczytywana informacja jest krótsza niż nbajtów.

Opis

Metoda read() próbuje odczytać 'nbyte' bajtów do bufora bufora, do którego odwołuje się 'buf' z pliku połączonego z deskryptorem otwartego dokumentu 'Fildes' lub 'fd'. Nie definiuje charakteru kilku jednoczesnych odczytów w tym samym strumieniu, FIFO lub jednostce końcowej.

Na dokumentach, które umożliwiają odczyt, proces odczytu rozpoczyna się od przesunięcia dokumentu, a przesunięcie jest zwiększane o liczbę odczytanych bajtów. Jeśli przesunięcie dokumentu jest na krawędzi pliku lub poza nią, nie ma odczytanych bajtów, a funkcja read() nie daje żadnego.

Gdy liczba wynosi 0, read() rozpozna błędy wymienione poniżej. Jeśli nie ma błędów lub jeśli read() nie jest rozliczane z błędami, read() daje zero przy liczbie 0 i dlatego nie ma innych reperkusji.

Jeśli liczba jest wyższa niż SSIZE_MAX, zgodnie z POSIX.1, o wyniku decyduje implementacja.

Wartość zwrotu

Liczba bajtów „read” i „preread” odwróconych po osiągnięciu musi być nieujemną liczbą całkowitą, a zero wskazuje na koniec pliku. Pozycja dokumentu jest przesunięta o ten numer lub, aby oznaczyć błąd, metody zwracają -1 i przypisują 'errno'. Gdy ta liczba jest mniejsza niż żądana liczba bajtów, nie jest to błędny bajt. Możliwe, że na razie dostępnych jest mniej bajtów.

Błędy

Funkcja pread i read zakończy się niepowodzeniem, jeśli wystąpią następujące błędy:

PONOWNIE:

Dokument lub deskryptor pliku „fd” należy do pliku bez gniazda, który został oznaczony jako nieblokujący (O NOBLOCK) i zablokuje odczyt.

BLOKADA EWOUL:

Deskryptor 'fd' należy do gniazda, które zostało oznaczone jako nieblokujące (O_NONBLOCK) i zablokuje odczyt.

EBADF:

„fd” może nie być użytecznym deskryptorem lub może nie być otwarty do czytania.

WYNIK:

Dzieje się tak, gdy „buf” znajduje się poza osiągalną przestrzenią adresową.

EINTR:

Przed odczytaniem danych informacyjnych połączenie mogło zostać przerwane sygnałem.

EINWAL:

Ten błąd pojawia się, gdy deskryptor 'fd' jest zaangażowany w obiekt, który nie jest odpowiedni do odczytu lub dokument został niezwiązany z flagą O_DIRECT i jednym lub drugim adresem podanym w 'buf' o wartości wskazanej w 'count ', lub przesunięcie dokumentu nie jest odpowiednio skojarzone.

EINWAL:

Deskryptor 'fd' mógł zostać utworzony za pomocą wywołania timerfd_create(2), a bufor o niepoprawnym rozmiarze został przekazany do odczytu.

EIO:

Jest to błąd wejścia/wyjścia. Występuje, gdy grupa procesów w tle próbuje odczytać ze swojego terminala regulacyjnego, a jeden lub drugi pomija lub blokuje SIGTTIN lub jego grupa procesów zostaje porzucona. Innym powodem tego błędu może być niskopoziomowy błąd wejścia/wyjścia podczas odczytu z dysku twardego lub taśmy. Inną potencjalną przyczyną EIO w plikach danych w sieci jest usunięcie doradczego blokowania deskryptora pliku i niepowodzenie tej blokady.

EISDIR:

Deskryptor pliku 'fd' należy do katalogu.

Uwagi:

Może również wystąpić wiele innych błędów, zależnych od obiektu połączonego z deskryptorem „fd”. Zarówno formularze size_t, jak i ssize_t są nieoznaczonymi i oznaczonymi typami danych liczbowych zdefiniowanymi przez POSIX.1. W systemie Linux przez funkcję odczytu (i równoważne wywołania systemowe) można przesłać maksymalnie 0x7ffff000 (2 147 479 552) bajtów, zwracając liczbę oryginalnie przesłanych bajtów (zarówno na platformach 32-bitowych, jak i 64-bitowych). W przypadku systemów plików NFS, tylko w pierwszej chwili, gdy znacznik czasu jest zmieniany przez odczytywanie niewielkich strumieni informacji, kolejne wywołania nie zrobią tego. Jest to wywoływane przez buforowanie atrybutów po stronie klienta, ponieważ, chociaż nie wszyscy, klienci NFS rezygnują z aktualizacji na serwerze przez st_atime (czas ostatniego dostępu do pliku), a odczyty po stronie klienta wykonane z bufora klienta nie wywołałyby zmian w st_atime. czas na serwerze, ponieważ nie są dostępne odczyty po stronie serwera. Usuwając buforowanie atrybutów po stronie klienta, można uzyskać dostęp do metadanych UNIX, ale w większości przypadków znacznie zwiększyłoby to obciążenie serwera i wpłynęłoby na wydajność.

Przykład 01:

Oto program w C demonstrujący wywołanie funkcji read w systemie Linux. Napisz poniższe polecenie tak, jak jest w nowym pliku. Dodaj biblioteki, a w głównej funkcji zainicjuj deskryptor i rozmiar. Deskryptor otwiera plik, a rozmiar służy do odczytu danych pliku.

Dane wyjściowe dla powyższego kodu byłyby takie, jak pokazano na poniższym obrazku.

Przykład 02:

Poniżej podano inny przykład ilustrujący działanie funkcji odczytu.

Utwórz kolejny plik i zapisz poniższy kod tak, jak jest w nim. Oto dwa deskryptory, fd1 i fd2, które mają swój własny dostęp do pliku otwartej tabeli. Więc dla foobar.txt, każdy deskryptor ma swoją lokalizację pliku. Pierwszy bajt foobar.txt jest tłumaczony z fd2, a wynikiem jest c = f, a nie c = o.

Wniosek

Przeczytaliśmy sprawnie funkcję odczytu POSIX w programowaniu w C. Miejmy nadzieję, że nie ma już żadnych wątpliwości.

Gry OpenTTD vs Simutrans
OpenTTD vs Simutrans
Creating your own transport simulation can be fun, relaxing and extremely enticing. That's why you need to make sure that you try out as many games as...
Gry OpenTTD Tutorial
OpenTTD Tutorial
OpenTTD is one of the most popular business simulation games out there. In this game, you need to create a wonderful transportation business. However,...
Gry SuperTuxKart for Linux
SuperTuxKart for Linux
SuperTuxKart is a great title designed to bring you the Mario Kart experience free of charge on your Linux system. It is pretty challenging and fun to...