标准流
此条目翻译自其他语言维基百科,需要相关领域的编者协助校对翻译。 |
在Unix和类Unix系统中,如同某些程式语言介面一样,标准串流是当一个电脑程式执行时,在它和它的环境间(典型为终端),事先连接的输入和输出频道。这三个I/O连结称作“标准输入”、“标准输出”和“标准错误输出”。
背景
在Unix之前的作业系统,程式必须明确指出连结到合适的输入和输出资料。对这当中的许多系统而言,这牵涉一些错综复杂而又与特定作业系统相关的事,是一件吓人的程式设计挑战。如控制环境设定、存取一个档案表格、决定区域资料集、和决定读卡机、磁带、磁碟、列印机、打卡机或互动式终端机。
Unix 提供许多开创产的进步,其中之一是提供 抽象设备 :它免除了程式须要知道或在意它正与哪个设备沟通。 Unix 借由资料串流的概念来消除这种复杂:一种资料位元组的有序序列,直到读到档案结尾。程式员亦可依需求写入而无须宣告写入多少或如何组织。
另一个 Unix 突破为预设自动连结输入和输出-程式(和程式设计师)不用为了典型输入-处理-输出程式建立输入和输出。相对地,之前作业系统通常要求一些-有时复杂-工作控制语言(Job Control Language)以建立连结,或者,相者近似于协调的责任。
既然 Unix 提供标准串流,Unix C 的执行环境被要求要支援它。结果不管什么作业系统, C 的执行环境(及 C 的衍生)都提供类似功能。
标准输入 (stdin)
标准输入是指输入至程式的资料(通常是文件)。程式要求以读(read)操作来传输资料。并非所有程式都要求输入。如dir或ls程式(显示一个目录中的档名)运行时不用任何输入。
标准输入的档案描述子为 0。在POSIX <unistd.h> 的定义是 STDIN_FILENO;相对应的 <stdio.h> 变数为 FILE* stdin ;类似地, <iostream> 变数为 std::cin 。
标准输出 (stdout)
标准输出是指程式写输出资料的串流。程式要求资料传输使用写的运算。并非所有程式都要求输出。如mv或ren程式在成功完成时是沉默的。
标准输出的档案描述子为 1 。POSIX <unistd.h> 定义是 STDOUT_FILENO;相对应的 <stdio.h> 变数为 FILE* stdout ;类似地, <iostream> 变数为 std::cout 。
标准错误输出 (stderr)
标准错误输出是另一输出串流,用于输出错误讯息或诊断。它独立于标准输出,且可以分别被重导。常见的目的则为启始这个程式的终端,即使其标准输出被重导亦如此。例如:一个管线中的程式的输出被重导到下一个程式,但错误讯息仍然直接流向文字终端机。
把标准输出和标准错误输出导到相同的目的地,如文字终端,是可以(且正常)的。讯息会以如同程式写入的顺序来出现,除非使用了缓冲。(例如,一个常见状况是,当标准错误串流未使用缓冲,但标准输出串流使用了缓冲;在这种情况下,如果标准输出的缓冲区还没满的话,较迟写到标准错误的文字可能会较早出现在终端。
标准错误输出的档案描述子为 2 ;POSIX <unistd.h> 定义为 STDERR_FILENO;相对的 <stdio.h> 变数 FILE* stderr。C++ <iostream> 标准表头档提供两个相关的变数: std::cerr 和 std::clog,前者用于无缓冲的而后者使用和其它 C++ 串流相同的缓冲机制。
大部分壳程式允许使用
>& filename
将标准输出和标准错误输出重导向到相同的档案。
Bourne-类壳程式允许使用
2>&1
将标准错误输出重导向到标准输出的目的。
年表
1950 年代: Fortran
Fortran 提供类于 Unix 档案描述子:UNIT=5
用于 stdin 、 UNIT=6
用于 stdout 和 UNIT=0
用于 stderr 。
! FORTRAN 77 example
PROGRAM MAIN
READ(UNIT=5,*)NUMBER
WRITE(UNIT=6,'(F5.3)')' NUMBER IS: ',NUMBER
END
1960: ALGOL 60
ALGOL 60因没有标准档案存取而受批评。
1968: ALGOL 68
ALGOL 68 的输入和输出机制合起来称为 transput 。 Cornelis H. A. Koster coordinated the definition of the transput standard. 这标准包含:stand in
、stand out
、stand error
和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)
)
输入: | 输出: |
---|---|
3.14159 |
Number is: +3.142 OR Number is: +3.142! |
1970 年代: C 和 Unix
在 C语言 中,标准输入、标准输出和标准错误输出分别连接到已存的 Unix 档案描述子 0 、1 和 2。
1995: Java
在Java中,标准串流被称为 System.in(标准输入)、System.out(标准输出)和 System.err(标准错误)。
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());
}
}
2000s: .NET
在 C# 和其它 .NET 语言中,标准串流为 System.Console.In
(标准输入)、System.Console.Out
(标准输出)和System.Console.Error
(标准错误)。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.Console.OpenStandardInput()
,System.Console.OpenStandardOutput()
和 System.Console.OpenStandardError()
所传回的System.IO.Stream
。
// 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 (System.ArgumentNullException) {
System.Console.Error.WriteLine("No number was entered!");
} catch (System.FormatException) {
System.Console.Error.WriteLine("The specified value is not a valid number!");
} catch (System.OverflowException) {
System.Console.Error.WriteLine("The specified number is too big!");
}
return -1;
}
' Visual Basic .NET example
Public Function Main() As Integer
Dim number As Double
Dim s As String
Try
s = System.Console.In.ReadLine()
number = CDbl(s)
System.Console.Out.WriteLine("Number is: {0:F3}", number)
Return 0
Catch e As System.InvalidCastException
' if CDbl() threw an exception
System.Console.Error.WriteLine("No number was entered!")
Return 1
End Try
End Function
当使用 System.Diagnostics.Process
类时,可以使用
StandardInput
、StandardOutput
和 StandardError
属性来存取程序的标准串流。
Console 并非指 Dos 的命令列视窗。
图形使用者介面
图形使用者介面很少使用标准串流。 重导图形使用者介面或建立管线是不实用的。 最近似的大概是从一个程式剪下(或复制)再贴到另一个。 既然需要人工使用者的运作,移动大量的贴上就不会特别有效率。 一个值得一提的例外为dwm铺砖式视窗管理器(tiling window manager),其会将导入标准输入的资料显示到状态列。
一些原本在 Unix 上的图形使用者介面程式仍会写错误讯息到标准错误输出。 其它可能会从标准输入取得档案,如许多 Unix 媒体播放程式。
GTK-Server 可以使用标准输入为沟通介面,以便互动式程式能理解图形使用者介面程式。
另见
参考
- KRONOS 2.1 Reference Manual, Control Data Corporation, Part Number 60407000, 1974
- NOS Version 1 Applications Programmer's Instant, Control Data Corporation, Part Number 60436000, 1978
- Level 68 Introduction to Programming on MULTICS (页面存档备份,存于互联网档案馆), Honeywell Corporation, 1981
- Evolution of the MVS Operating System (页面存档备份,存于互联网档案馆), IBM Corporation, 1981
- Lions' Commentary on UNIX Sixth Edition, John Lions, ISBN 1-57398-013-7, 1977
- Console Class, .NET Framework Class Library (页面存档备份,存于互联网档案馆), Microsoft Corporation, 2008
外部链接
- Standard Output Definition (页面存档备份,存于互联网档案馆) - by The Linux Information Project (LINFO)
- Video tutorial demonstrating stdout and stderr