Przejdź do zawartości

C/Strumień

Z Wikibooks, biblioteki wolnych podręczników.
< C

Znaczenie

[edytuj]

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

  • jest to sekwencja bajtów danych. Sekwencja bajtów wpływających do programu jest strumieniem wejściowym; ciąg bajtów wychodzących z programu jest strumieniem wyjściowym. Koncentrując się na strumieniach, nie musimy się tak bardzo martwić o to, dokąd zmierzają ani skąd pochodzą[2]
  • oznacza ciąg bajtów danych 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[3]
  • reprezentacja przepływu danych z jednej strony na drugą, np. z dysku do pamięci i z pamięci na dysk[4]. Użycie strumieni pozwala przesyłać duże ilości dane, w taki sposób aby nie zabrakło pamięci. [5]
  • strumień jest to kanał komunikacji z plikiem, urządzeniem lub procesem[6]
  • 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[7]



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

  • 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:[9]

standardowe

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

Standardowe strumienie ( ang. Standard Streams )[11]:

  • 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

Te strumienie są dostępne

  • w systemach operacyjnych zgodnych ze standardem POSIX w momencie uruchomienia "otrzymuje" od razu trzy otwarte
  • w pozostałych systemach[12] , domyślne zachowanie C otwiera te strumienie przy pierwszym wywołaniu ( ang. first reference). Nie musisz wywoływać funkcji fopen(), aby je otworzyć. Na przykład, jeśli następująca instrukcja zostanie określona bez poprzedzającej instrukcji fopen(), zapisuje liczbę dziesiętną n do strumienia stdout.
printf("%d\n",n);

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:[13]

  • 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)[14] – 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.[15] W bibliotece GNU C plik nagłówkowy sys/socket.h[16] 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[17][18][19] 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.[20]


Wieloplatformowy sieciowe API

  • APR (Apache Portable Runtime)

Potoki

[edytuj]

Potok (ang. pipe)[21] [22]– 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[23]

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


Przykład:[27]

 
#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)[28]

 
int fpeek(FILE *stream)
{
    int c;

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

    return c;
}


binarne

[edytuj]

Strumień binarny może obsługiwać dowolny rodzaj danych, w tym między innymi dane tekstowe. Bajty danych w strumieniu binarnym nie są tłumaczone ani interpretowane w żaden specjalny sposób; są odczytywane i zapisywane dokładnie tak, jak są. Strumienie binarne są używane głównie z plikami dyskowymi.[29] Odbiorca strumienia powinien znać format danych, aby poprawnie je odczytać i zinterpretować. Chyba, że będzie je odcyfrowywał ( deszyfrowł, dekryptował, kryptoanaliza)

Funkcje

[edytuj]

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

Przykłady

[edytuj]

Pomoc

[edytuj]

Zobacz również

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

Przypisy

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