流和底层的输入输出

文件和管道两者都是一般称为的 Wolfram 语言对象的例子. Wolfram 系统中的流是一个输入或输出源. 许多运算都是在流上进行的.

可以将 作为高层 Wolfram 语言输入输出函数. 它们的基础是直接在流上工作的底层输入-输出基元. 用这些基元,可以更多地控制 Wolfram 语言的输入和输出. 在编写从文件或管道存取中间数据的 Wolfram 语言程序时,需要进行精确的输入和输出控制.

把输出写入一个 Wolfram 语言流的底层步骤如下. 首先,调用 OpenWriteOpenAppend 去打开这个流,这告诉Wolfram 语言需要向一个文件或外部程序写入输出以及输出的形式. 打开一个流之后,调用 WriteWriteString 向这个流写入一个表达式或字符串序列. 完成后,用 Close 去关闭这个流.

"name"用名称指定的文件
"!name"用名称指定的命令
InputStream["name",n]输入流
OutputStream["name",n]输出流

Wolfram 语言中的流.

打开一个文件或管道时,Wolfram 系统产生一个流对象去指出打开的流与该文件或管道相关. 这个流对象一般包含该文件名或管道中外部命令名和一个唯一的数.

在流对象中使用一个唯一数的原因是可能同时会有几个流与同一个文件或外部程序相联系. 例如,可以在不同的地方使用同一个外部程序,每一次都与不同的流相关联.

然而,打开一个流后,当仅有一个对象和这个流相关联时,仍可以用一个简单的文件名或外部程序名取指代这个流.

打开一个输出到文件 的流.
In[1]:=
Click for copyable input
Out[1]=
向该文件写入一个表达式序列.
In[2]:=
Click for copyable input
由于仅有一个流与文件 相关联,所以能简单地用文件名去指代它.
In[3]:=
Click for copyable input
关闭这个流.
In[4]:=
Click for copyable input
Out[4]=
这是向该文件写入的内容.
OpenWrite["file"]打开一个输出到文件的流,清除该文件以前的内容
OpenWrite[]打开一个输出到新的临时文件的流
OpenAppend["file"]打开一个输出到文件的流,向已有内容追加数据
OpenWrite["!command"]打开一个输出到外部命令的流
Write[stream,expr1,expr2,]将表达式序列写到一个流,用一个换行结束输出
WriteString[stream,str1,str2,]将字符串序列写到一个流,没有额外换行
Close[stream]告诉 Wolfram 语言该流已经完成

底层输出函数.

调用 Write[stream,expr] 时,将一个表达式写入一个指定的流. 其默认情形是用 Wolfram 语言输入形式写入该表达式. 当调用 Write 写入一个表达式序列时,这些表达式就一个接一个地写入一个流中. 一般地,在相继表达式中无空格. 然而,在写完了所有表达式之后,Write 总用一个换行结束输出.

重新打开文件 .
In[6]:=
Click for copyable input
Out[6]=
向该文件写入一个表达式序列,然后关闭.
In[7]:=
Click for copyable input
Out[7]=
所有表达式用输入形式写入,同一 Write 给出的表达式放在同一行.

Write 提供了写出完整 Wolfram 语言表达式的途径. 有时需要写出较少结构化的数据. WriteString 用来写出任意字符串. 与 Write 不同,WriteString 不换行,也不加任何字符.

打开一个流.
In[9]:=
Click for copyable input
Out[9]=
向该流写入2个字符串.
In[10]:=
Click for copyable input
这里写入另一个字符串,然后关闭该流.
In[11]:=
Click for copyable input
Out[11]=
这里是该文件的内容. 这些字符串与给定的完全一样. 只有在明确给出换行符的地方才换行.
Write[{stream1,stream2},expr1,]将表达式写入一个流列表
WriteString[{stream1,stream2},str1,]将字符串写入流列表

将输出写入一个流列表.

函数 WriteWriteString 的重要特点之一是它们不仅可以向一个流,而且可以向一个流列表写入输出.

在使用 Wolfram 语言时,定义由流列表组成的通道 是方便的. 简单地令 Wolfram 语言向通道写入时,就把同一对象写入了几个流之中.

在标准交互式 Wolfram 语言进程中,有几个常用的输出通道. 它们指定某些类型输出的去向. 因此,例如,$Output 指定标准输出的去向,而 $Messages 指定信息的去向. 函数 Print 调用 Write$Output 通道工作. 同理,Message 调用 Write$Messages 通道工作. 在 "主循环" 中列出了典型 Wolfram 语言进程所使用的通道.

注意,通过 Wolfram Symbolic Transfer Protocol (WSTP) 运行 Wolfram 语言时使用不同的方式. 所有输出一般写入一个 WSTP 连接中,但每个输出块以一个表明类型的小包出现.

在大部分情况下,Wolfram 语言使用的文件名与外部命令名与计算机操作系统所使用的名称相对应. 但在一些系统中,Wolfram 系统支持各种具有特殊名称的流.

"stdout"标准输出
"stderr"标准错误

一些计算机系统中的特殊流.

特殊流 允许将输出送到操作系统提供的标准输出. 但要注意仅能在 Wolfram 语言的简单文本界面中使用. 当与 Wolfram 语言的交互更复杂时,这种流无法工作,试图使用这种流会带来很多麻烦.

选项名
默认值
FormatTypeInputForm默认输出格式
PageWidth78页按字符数的宽度
NumberMarks$NumberMarks近似数中是否包含记号
CharacterEncoding$CharacterEncoding特殊字符使用的编码

输出流的一些选项.

许多选项与输出流有关. 第一次用 OpenWriteOpenAppend 打开输出流时就可以定义这些选项.

这里打开一个流,指定 OutputForm 是默认输出格式.
In[13]:=
Click for copyable input
Out[13]=
将表达式写入这个流后关闭它.
In[14]:=
Click for copyable input
Out[14]=
这些表达式按 OutputForm 格式写入了这个流.

注意,将一个欲写入流的表达式放在 OutputFormTeXForm 等 Wolfram 语言格式指令内总可以覆盖对这个流所指定的输出格式.

选项 PageWidth 指定 Wolfram 语言文本输出的页宽. 所有输出都分成这种宽度的行. 不需要分行时应设置PageWidth->Infinity. 通常,设定与输出设备相符的PageWidth. 在许多系统中,运行一个程序去找到这个页宽值. 用 SetOptions 可以给出设置 PageWidth 的默认规则,例如,PageWidth:><<"!devicewidth",这就可以自动运行外部程序找出选项值.

打开一个流,指定页宽为20个字符.
In[16]:=
Click for copyable input
Out[16]=
写一个表达式后关闭该流.
In[17]:=
Click for copyable input
Out[17]=
表达式分为几行以便每行最多是20个字符.

CharacterEncoding 选项为一个字符串指定代码,该代码将在送到 WriteWriteString 给出的流中任意包含这个特殊字符的字符串中使用. 在需要改动国际字符集、或者需要某一输出设备接收不能处理的字符时,常常使用CharacterEncoding.

Options[stream]找出对流设置的选项
SetOptions[stream,opt1->val1,]对一个打开的流重写设置选项

操作流的选项.

打开一个具有默认设置的流.
In[19]:=
Click for copyable input
Out[19]=
改变打开流的 FormatType 选项.
In[20]:=
Click for copyable input
Options 显示了对打开的流所设置的选项.
In[21]:=
Click for copyable input
Out[21]=
关闭这个流.
In[22]:=
Click for copyable input
Out[22]=
Options[$Output]找出通道 $Output 中所有流的选项
SetOptions[$Output,opt1->val1,]对通道 $Output 中的所有流设置选项

操作标准输出通道的选项.

在进程中的每一处,Wolfram 语言保持一个当前打开的所有输入输出流以及它们选项的列表 Streams[]. 有时需要直接查看这一列表,但除过间接使用 OpenRead 等情况下,Wolfram 语言不允许修改这个列表.