C/Strumień
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 strumienie [10]
- niestandardowe
- Plikowe strumienie ( ang. file)
- Potok ( ang. pipe)
- Gniazdo ( ang socket)
- użytkownika
standardowe
[edytuj]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]- Plikowe strumienie ( ang. file)
- Potok ( ang. pipe)
- Gniazdo ( ang socket)
- użytkownika
pliki
[edytuj]Strumień plikowy jest to kanał komunikacji z plikiem. Więcej informacji: Czytanie i pisanie do plików
Gniazda
[edytuj]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:
- adres zdalny (np. adres IP, IPX, czy Ethernet)
- 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.
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]- 4programmers.net : szyfrowaniedeszyfrowanie_szyfr_kolumnowyplotkowy
- codereview question: byte-stream-implementation-in-c
- codereview question: file-stream-functions
- codereview question: ask-for-stream-of-character-input-and-print-number-of-uppercase-lowercase-charac
- codereview question: encoding-arbitrary-data-for-stream-transmission
- stackoverflow question: input-stream-into-c-program
- stackoverflow question : input-stream-on-c
- mandelbrot-book program by Claude Heiland-Allen i wikibooks
Pomoc
[edytuj]Zobacz również
[edytuj]- program filtrujący ( ang. filter program)[30]
Przypisy
[edytuj]- ↑ stackoverflow question: difference-between-file-pointer-stream-file-descriptor-and-file
- ↑ mycplus: c-programming-tutorials, input-output
- ↑ stackoverflow question : difference-between-fprintf-printf-and-sprintf
- ↑ social.msdn.microsoft Forum vstudio: difference-between-file-and-stream
- ↑ mathr blog: exponential mapping with kalles fraktaler
- ↑ gnu libc manual: Streams
- ↑ gnu software: libc manual - Streams
- ↑ Lista platform strumieniujących media ( ang. streaming media services )
- ↑ c-tutorials-notion-stream by Manish Bhojasia
- ↑ thradams : stream
- ↑ gnu software: libc manual -Standard-Streams
- ↑ ibm docs zos/2.2.0: output-using-c-c-standard-streams-redirection
- ↑ ibm docs : output-using-c-c-standard-streams-redirection
- ↑ Gniazdo (telekomunikacja) w wikipedii
- ↑ stackoverflow question: where-does-one-get-the-sys-socket-h-header-source-file
- ↑ opengroup : sys/socket.h
- ↑ gnu libc manual: Sockets
- ↑ C Language Examples of IPv4 and IPv6 Raw Sockets for Linux by David Buchan 2015
- ↑ socket(2) - Linux man page
- ↑ geeksforgeeks : socket-programming by Akshat Sinha
- ↑ popen(3) - Linux man page
- ↑ gnu libc manual: Pipes-and-FIFOs
- ↑ What is Stream in C Programming BestDotNetTraining ( Sandeep Soni)
- ↑ gnu libc manual : Binary-Streams
- ↑ gnu libc manual : Custom-Streams
- ↑ gnu libc manual: string-Streams
- ↑ stackoverflow question: how-would-i-create-a-file-output-stream-in-c-like-stdout
- ↑ stackoverflow question: c-equivalent-to-fstreams-peek
- ↑ mycplus tutoria : c-programming-tutorials/input-output/
- ↑ Filter_(software)#Unix in english wikipedia