В компьютерном программировании стандартные потоки — это предварительно соединенные входные и выходные каналы связи [1] между компьютерной программой и ее средой, когда она начинает выполняться. Три соединения ввода/вывода (I/O) называются стандартным вводом ( stdin ), стандартным выводом ( stdout ) и стандартной ошибкой ( stderr ). Первоначально ввод-вывод осуществлялся через физически подключенную системную консоль (ввод через клавиатуру, вывод через монитор), но стандартные потоки абстрагируют это. Когда команда выполняется через интерактивную оболочку , потоки обычно подключаются к текстовому терминалу , на котором запущена оболочка, но их можно изменить с помощью перенаправления или конвейера . В более общем смысле дочерний процесс наследует стандартные потоки своего родительского процесса .
Пользователи обычно знают стандартные потоки как каналы ввода и вывода, которые обрабатывают данные, поступающие от устройства ввода, или записывают данные из приложения. Данные могут быть текстовыми с любой кодировкой или двоичными данными . Когда программа запускается как демон , ее стандартный поток ошибок перенаправляется в файл журнала, обычно для целей анализа ошибок.
Потоки могут использоваться для объединения приложений в цепочку, а это означает, что выходной поток одной программы может быть перенаправлен в качестве входного потока в другое приложение. Во многих операционных системах это выражается перечислением имен приложений, разделенных вертикальной чертой, которую по этой причине часто называют символом конвейера . Хорошо известным примером является использование приложения нумерации страниц , такого как more , обеспечивающего пользователю контроль над отображением выходного потока на дисплее.
В большинстве операционных систем, предшествовавших Unix , программам приходилось явно подключаться к соответствующим устройствам ввода и вывода. Сложности, специфичные для ОС, сделали эту задачу программирования утомительной. Во многих системах необходимо было получить контроль над настройками среды, получить доступ к локальной таблице файлов, определить предполагаемый набор данных и правильно обращаться с оборудованием в случае устройства чтения перфокарт , накопителя на магнитной ленте , дисковода , линейного принтера , перфоратора карт. или интерактивный терминал.
Одним из нескольких революционных достижений Unix были абстрактные устройства , которые устранили необходимость для программы знать или заботиться о том , с какими устройствами она взаимодействует . Старые операционные системы навязывали программисту структуру записи и часто неортогональную семантику данных и управление устройством. Unix устранил эту сложность с помощью концепции потока данных: упорядоченной последовательности байтов данных, которую можно прочитать до конца файла . Программа также может записывать байты по своему желанию и в этом нет необходимости, и не может легко объявить их количество или группировку.
Еще одним прорывом в Unix было автоматическое связывание ввода и вывода с клавиатурой терминала и дисплеем терминала соответственно по умолчанию — программа (и программист) не делала абсолютно ничего для установления ввода и вывода для типичной программы ввода-обработки-вывода ( если только он не выбрал другую парадигму). Напротив, предыдущие операционные системы обычно требовали некоторого — часто сложного — языка управления заданиями для установления соединений, или эквивалентная нагрузка должна была быть организована программой. [ нужна ссылка ]
Поскольку Unix предоставлял стандартные потоки, среда выполнения Unix C также была обязана их поддерживать. В результате большинство сред выполнения C (и потомков C ), независимо от операционной системы, предоставляют эквивалентную функциональность.
Стандартный ввод — это поток, из которого программа считывает входные данные. Программа запрашивает передачу данных с помощью операции чтения . Не все программы требуют потокового ввода. Например, программы dir и ls (которые отображают имена файлов, содержащихся в каталоге) могут принимать аргументы командной строки , но выполнять свои операции без ввода потоковых данных.
Если не перенаправлено , стандартный ввод наследуется от родительского процесса. В случае интерактивной оболочки это обычно связано с устройством ввода терминала ( или псевдотерминала ), который в конечном итоге связан с клавиатурой пользователя .
В системах POSIX файловый дескриптор для стандартного ввода равен 0 (ноль); определение POSIX : ; соответствующая абстракция C предоставляется через глобальную переменную. Аналогично, глобальная переменная типа C++ обеспечивает абстракцию через потоки C++ . Подобные абстракции существуют в стандартных библиотеках ввода-вывода практически каждого языка программирования .<unistd.h>
STDIN_FILENO
<stdio.h>
FILE* stdin
std::cin
<iostream>
Стандартный вывод — это поток, в который программа записывает выходные данные. Программа запрашивает передачу данных при операции записи . Не все программы генерируют выходные данные. Например, команда переименования файла (также называемая mv , move или ren ) не сообщает об успехе.
Если не перенаправлено, стандартный вывод наследуется от родительского процесса. В случае интерактивной оболочки это обычно текстовый терминал , который инициировал программу.
Дескриптор файла для стандартного вывода равен 1 (один); определение POSIX : ; соответствующая переменная C равна ; аналогично, переменная C++ равна .<unistd.h>
STDOUT_FILENO
<stdio.h>
FILE* stdout
<iostream>
std::cout
Стандартная ошибка — это еще один поток вывода, обычно используемый программами для вывода сообщений об ошибках или диагностики. Это поток, независимый от стандартного вывода, и его можно перенаправить отдельно.
Это решает проблему полупредикатов , позволяя различать выходные данные и ошибки, и аналогично функции, возвращающей пару значений — см. Проблема полупредикатов: многозначный возврат . Обычным пунктом назначения является текстовый терминал , который запустил программу, чтобы обеспечить наилучшие шансы на то, что ее увидят, даже если стандартный вывод перенаправлен (поэтому его нелегко наблюдать). Например, вывод программы в конвейере перенаправляется на ввод следующей программы или в текстовый файл, но ошибки каждой программы по-прежнему поступают непосредственно на текстовый терминал, поэтому пользователь может просмотреть их в режиме реального времени. [2]
Допустимо и нормально направлять стандартный вывод и стандартную ошибку в одно и то же место назначения, например, в текстовый терминал. Сообщения появляются в том же порядке, в котором их записывает программа, если не используется буферизация . Например, в обычных ситуациях стандартный поток ошибок не буферизуется, но стандартный поток вывода буферизуется по строкам; в этом случае текст, записанный в стандартную ошибку позже, может появиться на терминале раньше, если буфер стандартного потока вывода еще не заполнен.
Дескриптор файла для стандартной ошибки определяется POSIX как 2 (два); заголовочный файл <unistd.h> содержит символ STDERR_FILENO
; [3] соответствующая <stdio.h>
переменная C равна FILE* stderr
. Стандартный заголовок C++ <iostream>
предоставляет две переменные, связанные с этим потоком: std::cerr
и std::clog
, первая из которых небуферизована, а вторая использует тот же механизм буферизации, что и все остальные потоки C++.
Оболочки в стиле Bourne позволяют перенаправлять стандартные ошибки в тот же пункт назначения, куда направляется стандартный вывод, используя
2>&1
Оболочки в стиле csh позволяют перенаправлять стандартные ошибки в тот же пункт назначения, куда направляется стандартный вывод, используя
>&
Стандартная ошибка была добавлена в Unix в 1970-х годах после того, как несколько напрасных прогонов фотонабора закончились набором сообщений об ошибках, а не отображением на пользовательском терминале. [4]
Фортран имеет эквивалент файловых дескрипторов Unix: по соглашению, многие реализации Фортрана используют номера единиц UNIT=5
для стандартного ввода, UNIT=6
стандартного вывода и UNIT=0
стандартного вывода. В Fortran -2003 встроенный ISO_FORTRAN_ENV
модуль был стандартизирован для включения именованных констант INPUT_UNIT
и для переносимого указания номеров модулей.OUTPUT_UNIT
ERROR_UNIT
! Пример FORTRAN 77 ПРОГРАММА ОСНОВНОЙ ЦЕЛЫЙ НОМЕР ЧТЕНИЕ ( UNIT = 5 , * ) НОМЕР ЗАПИСЬ ( UNIT = 6 , '(A,I3)' ) ' NUMBER IS: ' , NUMBER END
! Пример программы на Фортране 2003, основное использование iso_fortran_env неявное none целое :: чтение числа ( unit = INPUT_UNIT , * ) запись числа ( unit = OUTPUT_UNIT , '(a,i3)' ) 'Number is: ' , число конца программы
АЛГОЛ 60 критиковали за отсутствие стандартного доступа к файлам. [ нужна ссылка ]
Средства ввода и вывода Алгола 68 вместе назывались транспутом. [5] Костер координировал определение стандарта передачи . Модель включала три стандартных канала: stand in
, stand out
, и stand back
.
В языке программирования C стандартные потоки ввода, вывода и ошибок привязаны к существующим файловым дескрипторам Unix 0, 1 и 2 соответственно. [6] В среде POSIX вместо магических чисел следует использовать определения < unistd.h > STDIN_FILENO , STDOUT_FILENO или STDERR_FILENO . Также предоставляются указатели файлов stdin , stdout и stderr .
Кен Томпсон (разработчик и разработчик исходной операционной системы Unix) изменил сортировку в Unix версии 5, чтобы принять «-» как обозначение стандартного ввода, который распространился на другие утилиты и стал частью операционной системы как специальный файл в версии 8 . Диагностика была частью стандартного вывода до версии 6 , после чего Деннис М. Ритчи создал концепцию стандартной ошибки. [7]
В Java стандартные потоки обозначаются System.in
(для stdin), System.out
(для stdout) и System.err
(для stderr). [8]
public static void main ( String args [] ) { try { BufferedReader br = new BufferedReader ( новый InputStreamReader ( System . in )); Строка s = бр . читатьстроку (); двойное число = двойное . parseDouble ( s ); Система . вне . println ( "Число:" + число ); } catch ( Исключение е ) { System . ошибаюсь . println ( "Ошибка:" + e.getMessage ( ) ); } }
В C# и других языках .NET стандартные потоки обозначаются System.Console.In
(для stdin), System.Console.Out
(для stdout) и System.Console.Error
(для stderr). [9] Базовые возможности чтения и записи для потоков stdin и stdout также доступны непосредственно через класс System.Console
(например, System.Console.WriteLine()
могут использоваться вместо System.Console.Out.WriteLine()
).
System.Console.In
и System.Console.Out
являются System.Console.Error
объектами System.IO.TextReader
(stdin) и System.IO.TextWriter
(stdout, stderr), которые разрешают доступ только к базовым стандартным потокам на текстовой основе. Полный двоичный доступ к стандартным потокам должен осуществляться через System.IO.Stream
объекты, возвращаемые System.Console.OpenStandardInput()
, System.Console.OpenStandardOutput()
и System.Console.OpenStandardError()
соответственно.
// Пример C# public static int Main ( string [] args ) { try { string s = System . Консоль . В . ЧитатьЛинию (); двойное число = двойное . Разобрать ( ы ); Система . Консоль . Вне . WriteLine ( "Номер: {0:F3}" , номер ); вернуть 0 ; // Если Parse() выдал исключение } catch ( ArgumentNullException ) { System . Консоль . Ошибка . WriteLine ( "Номер не введен!" ); } catch ( FormatException ) { System . Консоль . Ошибка . WriteLine ( "Указанное значение не является допустимым числом!" ); } catch ( OverflowException ) { System . Консоль . Ошибка . WriteLine ( "Указанное число слишком велико!" ); } возврат — 1 ; }
'Пример Visual Basic .NETОткрытая функция Main () As Integer Попробуйте Dim s As String = System . Консоль . [ В ] . ReadLine () Тусклый номер As Double = Double . Разбор ( ы ) системы . Консоль . Вне . WriteLine ( "Число: {0:F3}" , число ) Возвращает 0 ' Если Parse() выдал исключение Catch ex As System . Система исключений ArgumentNullException . Консоль . [ Ошибка ] . WriteLine ( "Ни один номер не был введен!" ) Catch ex2 As System . Система исключений формата . Консоль . [ Ошибка ] . WriteLine ( "Указанное значение не является допустимым числом!" ) Catch ex3 As System . Система исключений переполнения . Консоль . [ Ошибка ] . WriteLine ( "Указанное число слишком велико!" ) End Try Возврат — 1 Конечная функция
При применении System.Diagnostics.Process
класса можно использовать свойства StandardInput
экземпляра , StandardOutput
и StandardError
этого класса для доступа к стандартным потокам процесса.
В следующем примере, написанном на Python , показано, как перенаправить стандартный ввод как на стандартный вывод, так и в текстовый файл.
#!/usr/bin/env питонимпортировать систему# Сохраняем текущий стандартный вывод, чтобы можно было вернуть sys.stdout# после того, как мы завершим наше перенаправлениеstdin_fileno = sys . стандартный вводstdout_fileno = sys . стандартный вывод# Перенаправляем sys.stdout в файлсис . stdout = открыть ( "myfile.txt" , "w" )Ctrl = 0для ввода в stdin_fileno : ctrs = ул ( ctr ) # Печатает на перенаправленный стандартный вывод () сис . стандартный вывод . напишите ( ctrs + ") это для перенаправления --->" + inps + " \n " ) # Печатает в фактически сохраненный обработчик стандартного вывода stdout_fileno . напишите ( ctrs + ") это по факту --->" + inps + " \n " ) Ctrl = Ctrl + 1# Закрываем файлсис . стандартный вывод . закрывать ()# Восстанавливаем sys.stdout в наш старый сохраненный обработчик файловсис . стандартный вывод = stdout_fileno
Графические пользовательские интерфейсы (GUI) не всегда используют стандартные потоки; они делают, когда графические интерфейсы являются оболочками базовых сценариев и/или консольных программ, например графический интерфейс менеджера пакетов Synaptic , который обертывает apt-команды в Debian и/или Ubuntu. Графические пользовательские интерфейсы, созданные с помощью инструментов сценариев, таких как Zenity и KDialog, в рамках проекта KDE [10], используют стандартный ввод stdin, stdout и stderr и основаны на простых сценариях, а не на законченном графическом интерфейсе, запрограммированном и скомпилированном на C/C++ с использованием Qt , GTK или других эквивалентная проприетарная структура виджетов.
Меню Services , реализованное в NeXTSTEP и Mac OS X , также аналогично стандартным потокам. В этих операционных системах графические приложения могут обеспечивать функциональность через общесистемное меню, которое работает с текущим выбором в графическом интерфейсе, независимо от того, в каком приложении.
Некоторые программы с графическим интерфейсом, в основном в Unix, по-прежнему записывают отладочную информацию в стандартную ошибку. Другие (например, многие медиаплееры Unix) могут читать файлы со стандартного ввода. Популярными программами для Windows, которые открывают отдельное окно консоли в дополнение к окнам графического интерфейса, являются эмуляторы pSX и DOSBox .
GTK-сервер может использовать стандартный ввод в качестве интерфейса связи с интерпретируемой программой для реализации графического интерфейса.
Парадигма Common Lisp Interface Manager «представляет» элементы графического интерфейса, отправляемые в расширенный поток вывода.