Strumienie standardowe — Standard streams
W programowaniu komputerowym , standardowe strumienie są połączone wejściowych i wyjściowych kanałów komunikacji pomiędzy programem komputerowym i jego otoczenia, kiedy zaczyna wykonanie. Trzy połączenia wejścia/wyjścia (I/O) nazywane są standardowym wejściem ( stdin ), standardowym wyjściem ( stdout ) i standardowym błędem ( stderr ). Pierwotnie I/O odbywało się poprzez fizycznie podłączoną konsolę systemową (wejście za pomocą klawiatury, wyjście za pomocą monitora), ale standardowe strumienie to abstrahują. Gdy polecenie jest wykonywane przez interaktywną powłokę , strumienie są zazwyczaj połączone z terminalem tekstowym , na którym działa powłoka , ale można je zmienić za pomocą przekierowania lub potoku . Bardziej ogólnie, proces potomny dziedziczy standardowe strumienie swojego procesu nadrzędnego .
Podanie
Użytkownicy na ogół znają standardowe strumienie jako kanały wejściowe i wyjściowe, które obsługują dane pochodzące z urządzenia wejściowego lub zapisują dane z aplikacji. Dane mogą być tekstem z dowolnym kodowaniem lub danymi binarnymi . W wielu nowoczesnych systemach standardowy strumień błędów programu jest przekierowywany do pliku dziennika, zwykle w celu analizy błędów.
Strumienie mogą być używane do łączenia aplikacji w łańcuchy, co oznacza, że strumień wyjściowy jednego programu może zostać przekierowany, aby był strumieniem wejściowym do innej aplikacji. W wielu systemach operacyjnych wyraża się to poprzez wypisanie nazw aplikacji, oddzielonych znakiem pionowej kreski, z tego powodu często nazywanym znakiem potoku . Dobrze znanym przykładem jest użycie aplikacji stronicowania , takiej jak more , zapewniającej użytkownikowi kontrolę nad wyświetlaniem strumienia wyjściowego na wyświetlaczu.
Tło
W większości systemów operacyjnych poprzedzających Uniksa programy musiały jawnie łączyć się z odpowiednimi urządzeniami wejściowymi i wyjściowymi. Specyficzne zawiłości systemu operacyjnego spowodowały, że było to żmudne zadanie programistyczne. W wielu systemach konieczne było uzyskanie kontroli nad ustawieniami środowisko, dostęp lokalny File Table określić zamierzony zestaw danych oraz sprzęt uchwyt poprawnie w przypadku czytnika kart poncz , napęd taśm magnetycznych , dyskietek , Line Printer , karta stempla lub terminal interaktywny.
Jednym z kilku przełomowych osiągnięć Uniksa były abstrakcyjne urządzenia , które wyeliminowały potrzebę, aby program wiedział lub dbał o to, z jakimi urządzeniami się komunikuje. Starsze systemy operacyjne wymuszały na programiście strukturę rekordów i często nieortogonalną semantykę danych oraz kontrolę urządzeń. Unix wyeliminował tę złożoność dzięki koncepcji strumienia danych: uporządkowanej sekwencji bajtów danych, które można odczytać do końca pliku . Program może również zapisywać bajty zgodnie z potrzebami i nie musi, i nie może łatwo zadeklarować ich liczby lub grupowania.
Kolejnym przełomem uniksowym było automatyczne powiązanie danych wejściowych i wyjściowych odpowiednio z klawiaturą terminala i wyświetlaczem terminala — program (i programista) nie zrobił absolutnie nic, aby ustanowić dane wejściowe i wyjściowe dla typowego programu wejścia-procesu-wyjścia (chyba że wybrał inny paradygmat). W przeciwieństwie do tego, poprzednie systemy operacyjne zwykle wymagały pewnego — często złożonego — języka kontroli zadań do nawiązywania połączeń lub równoważne obciążenie musiało być zaaranżowane przez program.
Ponieważ Unix dostarczał standardowe strumienie, środowisko uruchomieniowe Unix C było również zobowiązane do jego obsługi. W rezultacie większość środowisk wykonawczych C (i potomków C ), niezależnie od systemu operacyjnego, zapewnia równoważną funkcjonalność.
Wejście standardowe (stdin)
Standard input to strumień, z którego program odczytuje swoje dane wejściowe. Program żąda przesyłania danych za pomocą operacji odczytu . Nie wszystkie programy wymagają wprowadzania strumieniowego. Na przykład programy dir i ls (które wyświetlają nazwy plików zawartych w katalogu) mogą pobierać argumenty wiersza poleceń , ale wykonują swoje operacje bez wprowadzania danych strumieniowych.
O ile nie jest przekierowane , standardowe wejście jest dziedziczone z procesu nadrzędnego. W przypadku powłoki interaktywnej jest to zwykle związane z klawiaturą .
Deskryptor do standardowego wejścia wynosi 0 (zero); POSIX <unistd.h> definicja jest STDIN_FILENO
; odpowiadająca mu zmienna C <stdio.h> to FILE* stdin
; podobnie zmienna C++ <iostream> to std::cin
.
Wyjście standardowe (wyjście standardowe)
Standardowe wyjście to strumień, do którego program zapisuje swoje dane wyjściowe. Program żąda transferu danych z operacją zapisu . Nie wszystkie programy generują dane wyjściowe. Na przykład polecenie zmiany nazwy pliku (nazywane różnymi nazwami mv , move lub ren ) milczy w przypadku powodzenia.
O ile nie jest przekierowane , standardowe wyjście jest dziedziczone z procesu nadrzędnego. W przypadku powłoki interaktywnej jest to zwykle terminal tekstowy, który zainicjował program.
Deskryptor wyjścia standardowego wynosi 1 (jeden); POSIX <unistd.h> definicja jest STDOUT_FILENO
; odpowiadająca mu zmienna C <stdio.h> to FILE* stdout
; podobnie zmienna C++ <iostream> to std::cout
.
Błąd standardowy (stderr)
Błąd standardowy to kolejny strumień wyjściowy zwykle używany przez programy do wyświetlania komunikatów o błędach lub diagnostyki. Jest to strumień niezależny od standardowego wyjścia i może być przekierowany oddzielnie. Rozwiązuje to problem z półpredykatem , umożliwiając rozróżnienie wyjścia i błędów, i jest analogiczny do funkcji zwracającej parę wartości – zobacz Problem z półpredykatem: Zwrot wielowartościowy . Typowym miejscem docelowym jest terminal tekstowy, który uruchamiał program, aby zapewnić największą szansę na bycie widzianym, nawet jeśli standardowe wyjście jest przekierowywane (co nie jest łatwe do zaobserwowania). Na przykład wyjście programu w potoku jest przekierowywane do wejścia następnego programu, ale błędy z każdego programu nadal trafiają bezpośrednio do terminala tekstowego.
Dopuszczalne i normalne jest kierowanie standardowego wyjścia i standardowego błędu do tego samego miejsca docelowego, takiego jak terminal tekstowy. Komunikaty pojawiają się w tej samej kolejności, w jakiej program je zapisuje, chyba że w grę wchodzi buforowanie . Na przykład w typowych sytuacjach standardowy strumień błędów jest niebuforowany, ale standardowy strumień wyjściowy jest buforowany liniowo; w takim przypadku tekst wypisany do standardowego błędu później może pojawić się na terminalu wcześniej, jeśli bufor standardowego strumienia wyjściowego nie jest jeszcze pełny.
Deskryptor dla standardowego błędu określony jest przez POSIX jako 2 (dwa); <unistd.h> plik nagłówka zapewnia symbol STDERR_FILENO
; odpowiednia zmienna C <stdio.h> to FILE* stderr
. Standardowy nagłówek C++ <iostream> udostępnia dwie zmienne skojarzone z tym strumieniem: std::cerr
i std::clog
, przy czym pierwsza nie jest buforowana, a druga korzysta z tego samego mechanizmu buforowania, co wszystkie inne strumienie C++.
Powłoki w stylu Bourne'a umożliwiają przekierowanie standardowego błędu do tego samego miejsca docelowego, do którego kierowane jest standardowe wyjście
2>&1
Powłoki w stylu csh pozwalają na przekierowanie standardowego błędu do tego samego miejsca docelowego, do którego kierowane jest standardowe wyjście
>&
Błąd standardowy został dodany do Uniksa w latach 70. po tym, jak kilka zmarnowanych przebiegów fotoskładu zakończyło się komunikatami o błędach, które były składane, a nie wyświetlane na terminalu użytkownika.
Oś czasu
1950: Fortran
Fortran ma odpowiednik deskryptorów plików uniksowych: zgodnie z konwencją wiele implementacji Fortran używa numerów jednostek UNIT=5
dla stdin, UNIT=6
stdout i UNIT=0
stderr. W Fortran-2003, wrodzona ISO_FORTRAN_ENV
moduł został opracowany w celu m.in. nazwanych stałych INPUT_UNIT
, OUTPUT_UNIT
oraz ERROR_UNIT
przenośną podać numery jednostkowych.
! FORTRAN 77 example
PROGRAM MAIN
INTEGER NUMBER
READ(UNIT=5,*) NUMBER
WRITE(UNIT=6,'(A,I3)') ' NUMBER IS: ',NUMBER
END
! Fortran 2003 example
program main
use iso_fortran_env
implicit none
integer :: number
read (unit=INPUT_UNIT,*) number
write (unit=OUTPUT_UNIT,'(a,i3)') 'Number is: ', number
end program
1960: ALGOL 60
ALGOL 60 został skrytykowany za brak standardowego dostępu do plików.
1968: ALGOL 68
Urządzenia wejściowe i wyjściowe ALGOL 68 były zbiorczo określane jako transput. Koster koordynował definicję standardu transmisyjnego . Model zawiera trzy standardowe kanały: stand in
, stand out
, i stand back
.
# ALGOL 68 example #
main:(
REAL number;
getf(stand in,($g$,number));
printf(($"Number is: "g(6,4)"OR "$,number)); # OR #
putf(stand out,($" Number is: "g(6,4)"!"$,number));
newline(stand out)
)
|
|
Wejście: | Wyjście: |
---|---|
3.14159 |
Number is: +3.142 OR Number is: +3.142! |
1970: C i Unix
W języku programowania C standardowe wejścia, wyjścia i strumienie błędów są dołączane do istniejących uniksowych deskryptorów plików, odpowiednio 0, 1 i 2. W środowisku POSIX zamiast magicznych liczb należy używać definicji < unistd.h > STDIN_FILENO , STDOUT_FILENO lub STDERR_FILENO . Dostępne są również wskaźniki plików stdin , stdout i stderr .
Ken Thompson (projektant i realizator oryginalnego systemu operacyjnego Unix) zmodyfikował sortowanie w wersji 5 Unix, aby akceptować "-" jako reprezentujące standardowe wejście, które rozprzestrzeniło się na inne narzędzia i stało się częścią systemu operacyjnego jako specjalny plik w wersji 8 . Diagnostyka była częścią standardowego wyjścia w wersji 6 , po czym Dennis M. Ritchie stworzył koncepcję błędu standardowego.
1995: Jawa
W Javie standardowe strumienie są określane przez System.in
(dla stdin), System.out
(dla stdout) i System.err
(dla stderr).
public static void main(String args[]) {
try {
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
double number = Double.parseDouble(s);
System.out.println("Number is:" + number);
} catch (Exception e) {
System.err.println("Error:" + e.getMessage());
}
}
2000: .NET
W C# i innych językach .NET standardowe strumienie są określane przez System.Console.In
(dla stdin), System.Console.Out
(dla stdout) i System.Console.Error
(dla stderr). Podstawowe możliwości odczytu i zapisu strumieni stdin i stdout są również dostępne bezpośrednio przez klasę System.Console
(np. System.Console.WriteLine()
mogą być używane zamiast System.Console.Out.WriteLine()
).
System.Console.In
, System.Console.Out
I System.Console.Error
są System.IO.TextReader
(stdin) i System.IO.TextWriter
(stdout, stderr) przedmioty, które pozwalają na dostęp do podstawowych standardowych strumieni na zasadzie tylko tekst. Pełna binarne dostęp do standardowych strumieni muszą być wykonywane przez System.IO.Stream
obiektów zwróconych przez System.Console.OpenStandardInput()
, System.Console.OpenStandardOutput()
i System.Console.OpenStandardError()
odpowiednio.
// C# example
public static int Main(string[] args)
{
try {
string s = System.Console.In.ReadLine();
double number = double.Parse(s);
System.Console.Out.WriteLine("Number is: {0:F3}", number);
return 0;
// If Parse() threw an exception
} catch (ArgumentNullException) {
System.Console.Error.WriteLine("No number was entered!");
} catch (FormatException) {
System.Console.Error.WriteLine("The specified value is not a valid number!");
} catch (OverflowException) {
System.Console.Error.WriteLine("The specified number is too big!");
}
return -1;
}
' Visual Basic .NET example
Public Function Main() As Integer
Try
Dim s As String = System.Console.[In].ReadLine()
Dim number As Double = Double.Parse(s)
System.Console.Out.WriteLine("Number is: {0:F3}", number)
Return 0
' If Parse() threw an exception
Catch ex As System.ArgumentNullException
System.Console.[Error].WriteLine("No number was entered!")
Catch ex2 As System.FormatException
System.Console.[Error].WriteLine("The specified value is not a valid number!")
Catch ex3 As System.OverflowException
System.Console.[Error].WriteLine("The specified number is too big!")
End Try
Return -1
End Function
Przy stosowaniu System.Diagnostics.Process
klasy można użyć instancja właściwości StandardInput
, StandardOutput
i StandardError
z tej klasy dostępu standardowe strumienie procesu.
GUI
Graficzne interfejsy użytkownika (GUI) nie zawsze korzystają ze standardowych strumieni; robią to, gdy GUI są opakowaniami bazowych skryptów i/lub programów konsolowych, na przykład GUI menedżera pakietów Synaptic , który opakowuje polecenia apt w Debianie i/lub Ubuntu. GUI stworzone za pomocą narzędzi skryptowych, takich jak Zenity i KDialog przez projekt KDE, wykorzystują stdin, stdout i stderr i są oparte na prostych skryptach, a nie na kompletnym GUI zaprogramowanym i skompilowanym w C/C++ przy użyciu Qt , GTK lub innego równoważnego zastrzeżonego widgetu struktura.
Menu Usługi , jak realizowane na NeXTSTEP i Mac OS X , jest również analogiczne do standardowych strumieni. W tych systemach operacyjnych aplikacje graficzne mogą zapewniać funkcjonalność poprzez menu systemowe, które działa na bieżącym wyborze w GUI, bez względu na to, w jakiej aplikacji.
Niektóre programy z graficznym interfejsem użytkownika, głównie w systemie Unix, nadal zapisują informacje debugowania do standardowego błędu. Inne (takie jak wiele uniksowych odtwarzaczy multimedialnych) mogą odczytywać pliki ze standardowego wejścia. Popularne programy Windows, które oprócz okien GUI otwierają osobne okno konsoli, to emulatory pSX i DOSBox .
Serwer GTK może używać stdin jako interfejsu komunikacyjnego z interpretowanym programem do realizacji GUI.
The Common Lisp interfejsu Menedżera paradigm „prezenty” elementów GUI wysłane do rozszerzonego strumienia wyjściowego.
Zobacz też
- Przekierowanie (obliczenia)
- Strumień (obliczenia)
- Wejście wyjście
- Wejście/wyjście pliku C
- SYSIN i SYSOUT
- Standardowe strumienie w OpenVMS
Bibliografia
Źródła
- „ Standardowe strumienie ”, Biblioteka GNU C
- Instrukcja obsługi KRONOS 2.1 , Control Data Corporation, numer części 60407000, 1974
- NOS Version 1 Applications Programmer's Instant , Control Data Corporation, numer części 60436000, 1978
- Poziom 68 Wprowadzenie do programowania w MULTICS , Honeywell Corporation, 1981
- Ewolucja systemu operacyjnego MVS , IBM Corporation, 1981
- Komentarz Lions do UNIX Szóste wydanie , John Lions, ISBN 1-57398-013-7 , 1977
- Klasa konsoli, biblioteka klas .NET Framework , Microsoft Corporation, 2008
Zewnętrzne linki
- Definicja standardowego wejścia — autorstwa The Linux Information Project
- Definicja standardowego wyjścia — autorstwa The Linux Information Project
- Standardowa definicja błędu — autorstwa The Linux Information Project