C/Strumień

Z Wikibooks, biblioteki wolnych podręczników.
< C
Przejdź do nawigacji Przejdź do wyszukiwania

Znaczenie[edytuj]

Strumień ( ang stream) jest to termin o szerokim i zmiennym znaczeniu ( ang. a loose term) [1]

  • zwykle oznacza ciąg bajtów o nieokreślonej długości
    • Długość może być nieznana nawet nadawcy. Weźmy na przykład zadanie tworzenia strumienia w locie, prawdopodobnie z innych strumieni. Strumień może być nawet nieskończenie długi. Czasami długość strumienia jest znana, ale po prostu jest ignorowana. Czasami długość jest znana, ale nie w jednostkach użytkowych. Program odczytujący wiersze o zmiennej długości ze strumienia prawdopodobnie nie może zrobić nic użytecznego z długością strumienia w bajtach.
    • pojęcie to jest używane w komunikacji w odniesieniu do danych przekazywanych między autorem/nadawcą/producentem a czytelnikiem/odbiorcą/konsumentem
    • dostęp do strumienia jest sekwencyjny, niezależnie od tego, czy jest to konieczne, czy wygodne. Możliwość przeskoczenia do innego miejsca w strumieniu nie dyskwalifikuje automatycznie użycia tego terminu.
  • W C „strumień” jest abstrakcją; z perspektywy programu jest to po prostu producent (strumień wejściowy) lub konsument (strumień wyjściowy) bajtów. Może odpowiadać plikowi na dysku, potokowi, terminalowi lub innemu urządzeniu, takiemu jak drukarka lub tty. Typ FILE zawiera informacje o strumieniu. Zwykle nie ingerujesz bezpośrednio w zawartość obiektu FILE, po prostu przekazujesz do niego wskaźnik do różnych procedur I/O[2]
  • reprezentacja przepływu danych z jednej strony na drugą, np. z dysku do pamięci i z pamięci na dysk[3]. Użycie strumieni pozwala przesyłać duże ilości dane, w taki sposób aby nie zabrakło pamięci. [4]
  • strumień jest to kanał komunikacji z plikiem, urządzeniem lub procesem[5]
  • w Biblioteki Standardowej C ( ang. the C Standard Library ) strumień jest ogólnym interfejsem do wykonywania pewnych operacji wejścia i wyjścia( ang. I/O operations ).
    • Ze względów historycznych typ struktury danych C reprezentujący strumień nosi nazwę PLIK ( ang. FILE), a nie „strumień”. Ponieważ większość funkcji bibliotecznych dotyczy obiektów typu FILE*, czasami termin wskaźnik pliku jest również używany w znaczeniu „strumień”. Prowadzi to do niefortunnego zamieszania w terminologii w wielu książkach na temat C[6]



Jak istotne są strumienie pokazuje lista platform opartych na przesyłania strumieniowym mediów[7]

  • audio ( muzyka, podcasty ,radia internetowe)
    • Spotify
    • Tidal
  • video czyli filmy (VOD)
    • Netflix
    • YouTube
    • HBO Max & Discovery+
    • Amazon Prime Video
    • iQIYI
    • Tencent Video

Typy[edytuj]

strumienie w C:[8]

standardowe[edytuj]

Standardowe strumienie danych wejściowych, wyjściowych i błędów

Każdy program w momencie uruchomienia "otrzymuje" od razu trzy otwarte standardowe strumienie ( ang. Standard Streams )[9]:

  • stdin (wejście) = odczytywanie danych wpisywanych przez użytkownika
  • stdout (wyjście) = wyprowadzania informacji dla użytkownika
  • stderr (wyjście błędów) = powiadamiania o błędach

Pierwszy standardowy strumień ( stdin) jest używany do buforowania wejścia, a pozostałe dwa są używane do wyjścia.

 int main()
 {
     int var;
     scanf ("%d", &var); /* Użyj stdin do skanowania liczby całkowitej z klawiatury. */
     printf ("%d", var); /* Użyj stdout do wydrukowania liczby całkowitej, która została właśnie zeskanowana. */
     return 0;
 }

Domyślnie stdin wskazuje klawiaturę, a stdout i stderr wskazują ekran. Jest możliwe przekierowywanie danych wejściowych lub wyjściowych do pliku lub innych strumieni.


Warunki korzystania ze standardowych strumieni :

  • dołączyć plik nagłówkowy stdio.h
  • nie musimy otwierać ani zamykać strumieni standardowych ( tak jak w przypadku niestandardowych plików : fopen i fclose )


Funkcje które korzystają z stdin:[10]

  • getchar()
  • getchar_unlocked()
  • gets()
  • gets_unlocked()
  • scanf()
  • scanf_unlocked()
  • vscanf()
  • vscanf_unlocked()
  • wscanf()
  • wscanf_unlocked()
  • vwscanf()
  • vwscanf_unlocked()

Funkcje które korzystają z stdout:

  • printf()
  • printf_unlocked()
  • puts()
  • puts_unlocked()
  • putchar()
  • putchar_unlocked()
  • vprintf()
  • vprintf_unlocked()
  • wprintf()
  • wprintf_unlocked()
  • vwprintf()
  • vwprintf_unlocked()

Funkcje które korzystają z stderr: perror() perror_unlocked()

niestandardowe[edytuj]


pliki[edytuj]

Strumień plikowy jest to kanał komunikacji z plikiem. Więcej informacji: Czytanie i pisanie do plików

Gniazda[edytuj]

TCP Socket flow diagram

Gniazdo (ang. socket)[11] – pojęcie abstrakcyjne reprezentujące dwukierunkowy punkt końcowy połączenia. Dwukierunkowość oznacza możliwość wysyłania i odbierania danych. Wykorzystywane jest przez aplikacje do komunikowania się przez sieć w ramach komunikacji międzyprocesowej.

Gniazdo posiada trzy główne właściwości:

  • typ gniazda identyfikujący protokół wymiany danych
  • lokalny adres (np. adres IP, Internetwork Packet Exchange(IPX), czy Ethernet)
  • opcjonalny lokalny numer portu identyfikujący proces, który wymienia dane przez gniazdo (jeśli typ gniazda pozwala używać portów)

Gniazdo może posiadać (na czas trwania komunikacji) dwa dodatkowe atrybuty:

  1. adres zdalny (np. adres IP, IPX, czy Ethernet)
  2. opcjonalny numer portu identyfikujący zdalny proces (jeśli typ gniazda pozwala używać portów)

Adres IP wyznacza węzeł w sieci, numer portu określa proces w węźle, a typ gniazda determinuje sposób wymiany danych.

W systemach typu Unix obsługa gniazd jest implementowana w jądrze, a wykonywanie na nich operacji umożliwiają funkcje systemowe podobne do tych, jakich używa się w stosunku do plików.

Nie wszystkie systemy operacyjne obsługują gniazda, Windows nie ma pliku sys/socket.h ale jest plik winsock2.h.[12] W bibliotece GNU C plik nagłówkowy sys/socket.h[13] istnieje niezależnie od systemu operacyjnego, a funkcje gniazd zawsze istnieją, ale jeśli system tak naprawdę nie obsługuje gniazd, te funkcje zawsze zawodzą.

    
#ifdef __WIN32__
# include <winsock2.h>
#else
# include <sys/socket.h>
#endif


Programowanie gniazd[14][15][16] to sposób łączenia dwóch węzłów w sieci w celu komunikowania się ze sobą. Jedno gniazdo (węzeł) nasłuchuje na określonym porcie w adresie IP, podczas gdy drugie gniazdo łączy się z drugim, aby utworzyć połączenie. Serwer tworzy gniazdo odbiornika, podczas gdy klient łączy się z serwerem.[17]


Wieloplatformowy sieciowe API

  • APR (Apache Portable Runtime)

Potoki[edytuj]

Potok (ang. pipe)[18] [19]– jeden z mechanizmów komunikacji międzyprocesowej umożliwiający wymianę danych pomiędzy dwoma procesami. Odbywa się to najczęściej poprzez połączenie standardowego wyjścia jednego procesu ze standardowym wejściem drugiego.

Prosty schemat potoku POSIX (Unix) standardowych strumieni. Przedstawiono: terminal tekstowy, uruchomione programy w potoku, strumienie standardowe wejście stdin, standardowe wyjście stdout, standardowe wyjście błędu stderr.

Do stworzenia nienazwanego potoku służy wywołanie systemowe pipe(). Prototyp funkcji bibliotecznej znajduje się w pliku nagłówkowym unistd.h i ma następującą postać:

   
int pipe(int fields[2]);

Funkcja pipe() umieszcza dwa nowe deskryptory plików w tablicy fields[] (fields[0] – deskryptor pliku tylko do odczytu, fields – deskryptor pliku tylko do zapisu) i zwraca 0 w przypadku powodzenia lub -1 w przypadku błędu.

Funkcja pipe() często używana jest w połączeniu z funkcją fork() w celu zapewnienia komunikacji między procesem macierzystym oraz jego procesami potomnymi.

Strumienie zdefiniowane przez uzytkownika[edytuj]

Typy

  • binarne[20]
    • własnego typu (ang. Custom Streams)[21]
  • tekstowe
    • łancuchowe ( ang. String Streams ) obsługują funkcje fmemopen i open_memstream[22]


Przykład:[23]

 
#include <stdio.h>

int main(void) {

  int filedes = 3; // New descriptor
  FILE *stream = fdopen (filedes, "w"); // Ze względów historycznych typ struktury danych C reprezentujący strumień nosi nazwę PLIK ( ang. FILE), a nie „strumień”
  fprintf (stream, "hello, world!\n");
  fprintf (stream, "goodbye, world!\n");
  fclose (stream);

  return 0;
}

tekstowe[edytuj]

Czytanie następnego znaku ( ang. to peek at the next character)[24]

 
int fpeek(FILE *stream)
{
    int c;

    c = fgetc(stream);
    ungetc(c, stream);

    return c;
}

Funkcje[edytuj]

Język C udostępnia wiele standardowych funkcji bibliotecznych wejścia/wyjścia. Funkcje te są zdefiniowane w standardowej bibliotece <stdio.h>

Pomoc[edytuj]

Zobacz również[edytuj]

  • program filtrujący ( ang. filter program)[25]

Przypisy[edytuj]

  1. stackoverflow question: difference-between-file-pointer-stream-file-descriptor-and-file
  2. stackoverflow question : difference-between-fprintf-printf-and-sprintf
  3. social.msdn.microsoft Forum vstudio: difference-between-file-and-stream
  4. mathr blog: exponential mapping with kalles fraktaler
  5. gnu libc manual: Streams
  6. gnu software: libc manual - Streams
  7. Lista platform strumieniujących media ( ang. streaming media services )
  8. c-tutorials-notion-stream by Manish Bhojasia
  9. gnu software: libc manual -Standard-Streams
  10. ibm docs : output-using-c-c-standard-streams-redirection
  11. Gniazdo (telekomunikacja) w wikipedii
  12. stackoverflow question: where-does-one-get-the-sys-socket-h-header-source-file
  13. opengroup : sys/socket.h
  14. gnu libc manual: Sockets
  15. C Language Examples of IPv4 and IPv6 Raw Sockets for Linux by David Buchan 2015
  16. socket(2) - Linux man page
  17. geeksforgeeks : socket-programming by Akshat Sinha
  18. popen(3) - Linux man page
  19. gnu libc manual: Pipes-and-FIFOs
  20. gnu libc manual : Binary-Streams
  21. gnu libc manual : Custom-Streams
  22. gnu libc manual: string-Streams
  23. stackoverflow question: how-would-i-create-a-file-output-stream-in-c-like-stdout
  24. stackoverflow question: c-equivalent-to-fstreams-peek
  25. Filter_(software)#Unix in english wikipedia