C/Strumień
ZnaczenieEdytuj
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
TypyEdytuj
strumienie w C:[8]
- Standardowe strumienie
- niestandardowe
- Plikowe strumienie ( ang. file)
- Potok ( ang. pipe)
- Gniazdo ( ang socket)
- użytkownika
standardoweEdytuj
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()
niestandardoweEdytuj
- Plikowe strumienie ( ang. file)
- Potok ( ang. pipe)
- Gniazdo ( ang socket)
- użytkownika
plikiEdytuj
Strumień plikowy jest to kanał komunikacji z plikiem. Więcej informacji: Czytanie i pisanie do plików
GniazdaEdytuj
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:
- 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.[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)
PotokiEdytuj
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.
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 uzytkownikaEdytuj
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;
}
tekstoweEdytuj
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;
}
FunkcjeEdytuj
Język C udostępnia wiele standardowych funkcji bibliotecznych wejścia/wyjścia. Funkcje te są zdefiniowane w standardowej bibliotece <stdio.h>
PomocEdytuj
Zobacz równieżEdytuj
- program filtrujący ( ang. filter program)[25]
PrzypisyEdytuj
- ↑ stackoverflow question: difference-between-file-pointer-stream-file-descriptor-and-file
- ↑ 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
- ↑ gnu software: libc manual -Standard-Streams
- ↑ 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
- ↑ 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
- ↑ Filter_(software)#Unix in english wikipedia