文件、流和外部运算

读取和写入 Wolfram 系统文件

在外部文件中存储 Wolfram 语言表达式

可以使用计算机系统上的文件来存储 Wolfram 语言的定义和结果. 最通用的方法是将所有内容存储为适合 Wolfram 语言输入的纯文本格式. 通过这种方法,在一个计算机系统上运行的 Wolfram 语言版本可生成在任何计算机系统上运行的版本都可以读取的文件. 此外,其他标准程序(如文本编辑器)也可对文件进行操作.
<<file or Get["file"]
读取 Wolfram 语言输入文件,返回文件中最后一个表达式
FilePrint["file"]
显示文件的内容
expr>>file or Put[expr,"file"]
将表达式写入文件
expr>>>file or PutAppend[expr,"file"]
将表达式追加到文件中
读取和写入文件.
展开 ,将结果输出到名为 tmp 的文件中:
以下是 tmp 的内容,可直接用作 Wolfram 语言的输入:
读入 tmp 文件,运行其中含有的 Wolfram 语言输入:
显示文件 factors 的内容:
读取文件并返回文件中的最后一个表达式:
如果 Wolfram 语言找不到要求读取的文件,会显示一条消息,然后返回符号 $Failed
<<file 读取文件时,Wolfram 语言将返回它在文件中运行的最后一个表达式. 通过在文件中最后一个表达式的末尾添加分号,或在该表达式之后添加 Null,可以避免读取文件时出现任何可见的结果.
如果 Wolfram 语言在读取文件时遇到语法错误,它将报告该错误,跳过文件的其余部分,然后返回 $Failed. 如果语法错误发生在使用 BeginPackage 和其他上下文操作函数的软件包中,则 Wolfram 语言会尝试将上下文恢复到软件包被读取之前的状态.

保存多个 Wolfram 语言表达式

Wolfram 语言输入文件可以包含任意数量的表达式. 但是,每个表达式必须从新的一行开始. 表达式可以根据需要连续占据多行. 就像在标准的交互式 Wolfram 语言会话中一样,表达式一旦完成就立即对其进行处理. 请注意,在文件中,与交互式会话不同,可以在任何位置插入空白行而不会产生任何影响.
expr>>>file 时,Wolfram 语言会将你给出的每个新表达式附加到文件末尾. 如果使用 expr>>file,Wolfram 语言会清除掉文件中以前的所有内容,然后将 expr 放入文件中.
将表达式写入文件 tmp 中:
文件的内容:
将另一个表达式追加到同一文件中:
两个表达式现在都在文件中:
如果你熟悉命令行操作系统,会意识到 Wolfram 语言重定向操作符 >>>>><< 与命令行操作符 >>>< 类似.

以不同的格式保存 Wolfram 语言表达式

当你用 >>>>> 将表达式写入文件时,通常以 Wolfram 语言输入格式给出表达式,以便可以将其读回 Wolfram 语言中. 但是,有时你可能希望以其他格式保存表达式. 可以通过在表达式周围添加格式指令(如 OutputForm)来完成.
用输出格式将表达式写入文件 tmp 中:
现在,tmp 中的表达式的格式为输出格式:

保存 Wolfram 语言对象的定义

使用文件的最常见原因之一是保存 Wolfram 语言对象的定义,以便能够在后续的 Wolfram 语言会话中再次读取它们. 运算符 >>>>> 使你可以将 Wolfram 语言表达式保存在文件中. 可以使用函数 Save 以适合在后续 Wolfram 语言会话中执行的格式保存 Wolfram 语言对象的完整定义.
Save["file",symbol]
将符号的完整定义保存在文件中
Save["file","form"]
保存名称与字符串模式 form 匹配的符号的定义
Save["file","context`"]
保存指定上下文中所有符号的定义
Save["file",{object1,object2,}]
保存几个对象的定义
将定义保存到纯文本文件中.
对符号 a 赋值:
Savea 的定义写入文件:
保存在文件中的 a 的定义:
定义一个依赖于先前定义的符号 a 的函数 f
f 的完整定义保存到文件中:
文件不仅包含 f 本身的定义,还包含 f 所依赖的符号 a 的定义:
清除 fa 的定义:
只需读取文件 ffile 即可恢复保存的定义:
函数 Save 使用输出格式 DefinitionFullDefinition,用来显示 Wolfram 语言符号的定义. 在某些情况下,可能会发现直接使用这些输出格式很方便.
输出格式 Definition[f] 显示为 f 所作的定义:
FullDefinition[f] 还包括 f 所依赖的对象的定义:
在 Wolfram 语言中定义新对象时,通常定义会依赖于之前定义的其他对象. 如果想在后续的 Wolfram 语言会话中重建新对象的定义,那么不仅要保存对象自身的定义,还要保存它所依赖的其他对象的定义. 函数 Save 会查看你要求保存的对象的定义,并自动保存所依赖的其他对象的所有定义. 但是,为了避免保存大量不必要的内容,Save 从来不包含有 Protected 属性的符号的定义. 它假定这些符号的定义是内置的. 但是,在保全这些定义的情况下,将 Save 生成的输出读回到新的 Wolfram 语言会话中将始终能建立对象的定义,该定义应与之前的定义完全一样.

以编码形式保存 Wolfram 语言定义

创建用于输入到 Wolfram 语言的文件时,通常希望它们只包含可以直接进行读取或修改的纯文本内容. 但是,有时可能希望对文件的内容进行编码,使得它们不能直接作为纯文本被读取或修改,但可以被加载到 Wolfram 语言中. 可以使用 Wolfram 语言函数 Encode 创建被编码过的文件.
Encode["source","dest"]
将文件 source 被编码过的版本写入文件 dest
<<dest
读入编码文件
Encode["source","dest","key"]
用指定密钥进行编码
Get["dest","key"]
读入用密钥编码过的文件
Encode["source","dest",MachineID->"ID"]
创建只能在有特定 ID 的计算机上读取的编码文件
创建和读取编码文件.
将纯文本表达式写入文件 tmp
将文件 tmp 被编码过的版本写入文件 tmp.x
这是编码文件的内容. 唯一可识别的部分是开头的特殊 Wolfram 语言注释:
即使文件已被编码,仍然可以使用 << 运算符将其读入 Wolfram 语言中:
DumpSave["file.mx",symbol]
用 Wolfram 语言内部格式保存符号的定义
DumpSave["file.mx","context`"]
保存上下文中所有符号的定义
DumpSave["file.mx",{object1,object2,}]
保存几个符号或上下文的定义
DumpSave["package`",objects]
用专门选择的名称将定义保存到文件中
用 Wolfram 系统内部格式保存定义.
如果必须读入非常大或复杂的定义,通常会发现以 Wolfram 系统内部格式(而不是文本)保存这些定义会更高效. 可以使用 DumpSave 来完成.
以 Wolfram 系统内部格式保存 f 的定义:
仍然可以使用 << 读取定义:
<< 可识别出文件内包含 Wolfram 系统内部格式的定义,并相应地进行操作. 微妙之处在于,Wolfram 系统内部格式因计算机系统而异,在一台计算机上创建的 .mx 并不能总是在另一台计算机上读取.
如果使用 DumpSave["package`",],则 Wolfram 语言会将定义写入到名称为 package.mx/system/package.mx 的文件中,其中 system 标志着计算机系统的类型.
创建一个文件,该文件的名称反映所使用的计算机系统的名称:
<< 自动选取名称适合你的计算机系统的文件:
外部程序
在大多数计算机系统上,可以从 Wolfram 语言中执行外部程序或命令. 通常,你希望将在 Wolfram 语言中生成的表达式发送到外部程序,或者从外部程序中获取结果,并将其读入 Wolfram 语言中.
Wolfram 语言支持与外部程序进行通信的两种基本形式:结构化和非结构化.
Structured communication
用 WSTP 与 WSTP 兼容的外表程序交换表达式
Unstructured communication
用文件读写操作交换普通文本
Wolfram 语言中与外部程序通信的两种方式.
结构化通信的要点是与专门为处理此类对象而设置的外部程序交换完整的 Wolfram 语言表达式. 结构化通信的基础是Wolfram Symbolic Transfer Protocol (WSTP) 系统,WSTP 和外部程序的通讯对此进行了论述.
非结构化通信包括从外部程序发送和接收普通文本. 基本思想是将外部程序文件像文件一样对待,并支持相同类型的读写操作.
<<file
读入文件
<<"!command"
运行外部指令,并读入产生的输出
expr>>"!command"
将文本形式的 expr 提供给外部指令
ReadList["!command",Number]
运行外部指令,并读入它产生的数字列表
与外部程序通信的一些方法.
总的来说,无论在哪里使用普通文件名,Wolfram 语言允许你给出一个管道,以外部命令的形式编写,在前面加上一个感叹号就可以了. 使用管道时,Wolfram 语言将执行外部指令,并从中发送或接收文本.
FactorInteger 的结果发送到外部程序 lpr. 在许多 Unix 系统上,该程序会打印输出:
执行外部命令 echo$TERM,然后将结果作为输入读入到 Wolfram 语言中:
在基于文本的界面中,在行的开头放上 !,即可将该行的其余部分作为外部命令执行. squares 是一个外部程序,可显示数字及其平方.
In[1]:= !squares 4

1 1
2 4
3 9
4 16
运行外部命令 squares 4,然后从产生的输出中读取数字:
需要注意的一点是,如果名称中不包含空格或其他特殊字符,则可将 <<>> 右侧的管道名称的双引号删除.
Wolfram 语言中的管道为与外部程序的非结构化通信提供了非常通用的机制。在许多计算机系统上,Wolfram 语言管道是使用底层操作系统中的管道机制来实现的;但是,在某些情况下,将使用其他进程间通信机制. Wolfram 语言中非结构化通信的一个限制是,给定管道只能用于输入或输出,不能同时用于两者. 为了进行真正的双向通信,需要使用 WSTP.
即使是非结构化通信,仍然可以通过使用临时文件来进行一些更复杂的设置. 基本思想是将数据写入文件,然后根据需要读取.
OpenWrite[]
在你的计算机系统上,在临时文件的默认区域中打开一个具有唯一名称的新文件
打开一个临时文件.
特别是在使用临时文件时,你可能会发现能够运行不显式发送或接收来自 Wolfram 语言的数据的外部指令很有用. 可以通过 Wolfram 语言函数 Run 来完成.
Run["command",arg1,]
在 Wolfram 语言内部运行外部指令
不使用输入或输出,运行外部指令.
执行外部 Unix 指令 date.返回的值是操作系统的退出代码
请注意,使用 Run 时,不要在指令前加感叹号. Run 接受你指定的参数的文本形式,然后将它们连接在一起,中间要加上空格,然后将所得字符串作为外部壳指令执行.
重要的是要认识到 Run 永远不会捕获外部指令的任何输出. 因此,输出到哪里完全由操作系统决定. 同样,Run 不为外部指令提供输入. 这意味着命令可以通过操作系统提供的任何机制获取输入. 有时外部命令可能能够访问 Wolfram 语言本身使用的输入和输出流. 在某些情况下,这可能正好就是你想要的. 但是,如果你是在前端使用 Wolfram 语言,这样做则可能会造成很大的麻烦.
RunThrough["command",expr]
运行 command,用 expr 作为输入,将输出读回 Wolfram 语言
通过外部程序运行 Wolfram 语言表达式.
如上所述,不能同时使用 <<>> 从外部程序发送和接收数据. 但是,通过使用临时文件,实际上可以使用非结构化通信同时从外部程序发送和接收数据.
函数 RunThrough 将表达式文本写入临时文件,然后将该文件作为输入提供给外部程序,并抓取输出作为 Wolfram 语言的输入. 注意,在 RunThrough 中,和 Run 一样,不要在指令前加感叹号.
将表达式 789 提供给外部程序 cat,此处只是回显表达式的文本. 然后,将 cat 的输出读回到 Wolfram 语言:
SystemOpen["target"]
用计算机系统上关联的程序打开指定文件、URL 或其他目标
用外部程序打开文件.
使用系统首选的网页浏览器打开 URL:
SystemOpen 使用操作系统中的设置来确定如何打开 URI 或文件. 打开文件时,它通常使用与双击文件图标时使用的程序相同的程序.
流与低级输入和输出
文件和管道都是广义的 Wolfram 系统对象(称为)的例子. Wolfram 系统中的流是输入或输出的来源. 可以对流执行许多操作.
可以将 >><< 视为高级的 Wolfram 系统输入输出功能. 它们基于一组直接与流一起使用的较低级别的输入输出基元. 通过使用这些基元,可以对 Wolfram 系统怎样执行输入和输出进行更精确的控制. 例如,如果编写从文件或管道中存储或获取中间数据的 Wolfram 系统程序,通常需要使用这些基元.
Wolfram 系统中将输出写入流中的基本底层方案如下:首先,调用 OpenWriteOpenAppend 打开流,告诉 Wolfram 系统将输出写入特定的文件或外部程序,并指定以什么形式写入输出. 打开流后,可以调用 WriteWriteString 将表达式或字符串序列写入流. 完成后,请调用 Close 关闭流.
"name"由名称指定的文件
"!name"
由名称指定的指令
InputStream["name",n]
输入流
OutputStream["name",n]
输出流
Wolfram 系统中的流.
当你打开文件或管道时,Wolfram 系统会创建一个流对象,指定与文件或管道关联的打开的流. 通常,流对象包含文件名或管道中使用的外部指令以及唯一编号.
流对象需要包含唯一编号的原因是,一般情况下,可以同时将多个流连接到同一文件或外部程序. 例如,可以启动多个一样的外部程序,每一个都连接到不同的流.
但是,打开流后,只要只有一个流与该对象关联,就仍然可以使用简单的文件名或外部命令名来引用它.
打开到文件 tmp 的输出流:
将表达式序列写入文件:
由于只有只有一个流与文件 tmp 关联,因此你可以简单地通过文件名来引用它:
关闭流:
这是写入文件的内容:
OpenWrite["file"]
打开到文件的输出流, 清除文件中以前的内容
OpenWrite[]
打开到新的临时文件的输出流
OpenAppend["file"]
打开到文件的输出流,追加到文件中已有内容的后面
OpenWrite["!command"]
打开到外部指令的输出流
Write[stream,expr1,expr2,]
将表达式序列写入流,以换行符结束输出
WriteString[stream,str1,str2,]
将字符串序列写入流,不加换行符
Close[stream]
告诉 Wolfram 系统不再使用流
低级输出函数.
调用 Write[stream,expr] 时,将表达式写入指定的流. 默认是用 Wolfram 系统输入形式写入表达式.如果调用 Write 写入表达式序列,它将把这些表达式一个接一个地写入流中. 通常,相邻表达式之间不留空格. 但是,写完所有表达式后,Write 总是以换行符结束输出.
重新打开文件 tmp
将表达式序列写入文件,然后关闭文件:
以输入格式写入所有表达式. 一个 Write 指令中的表达式被写在同一行上:
Write 提供了一种写出完整 Wolfram 语言表达式的方式. 但是,有时你可能希望写出结构化程度较低的数据. WriteString 允许写出任何字符串. 与 Write 不同,WriteString 不添加换行符或其他字符.
打开流:
将两个字符串写入流:
写入另一个字符串,然后关闭流:
这是文件的内容. 完全按照指定的顺序写出字符串,只包含明确给出的换行符:
Write[{stream1,stream2},expr1,]
将表达式写入一组流
WriteString[{stream1,stream2},str1,]
将字符串写入一组流
将输出写入一组流.
函数 WriteWriteString 的一个重要功能是不仅允许将输出写入单个流,而且还可以写入一组流.
在使用 Wolfram 系统时,定义包含一系列流的通道通常会带来很多方便. 然后,只需简单地告诉 Wolfram 系统写入到通道,即可自动将同一对象写入多个流.
在标准的交互式 Wolfram 系统会话中,通常会定义几个输出通道. 它们指定应将特定种类的输出发送到何处. 因此,例如,$Output 指定标准输出应去到何处,而 $Messages 指定消息应去到何处. 函数 Print 实际上就是通过调用 Write$Output 通道来完成. 同样,通过调用 Write$Messages 通道可完成 Message. 主循环列出了典型 Wolfram 系统会话中使用的通道.
请注意,通过 Wolfram Symbolic Transfer Protocol (WSTP) 运行 Wolfram 系统时,通常会使用其他方法. 通常将所有输出写入单个 WSTP 链接,但是每条输出都显示在表明其类型的数据包中.
大多数情况下,在 Wolfram 系统中使用的文件名或外部指令与计算机操作系统使用的完全一致. 但是,在某些系统上,Wolfram 系统支持各种具有特殊名称的流.
"stdout"
标准输出
"stderr"
标准错误
某些计算机系统上使用的特殊流.
特殊流 "stdout" 使你可以将输出提供给操作系统提供的标准输出. 但是请注意,只能将此流与 Wolfram 系统的基于文本的简单接口一起使用. 如果与 Wolfram 系统的交互比较复杂,则此流将无法工作,并且使用它可能会造成很大的麻烦.
选项名称
默认值
FormatTypeInputForm
使用的默认输出格式
PageWidth78
页面的宽度,以字符数给出
NumberMarks$NumberMarks
是否在近似数字中包含 ` 标记
CharacterEncoding$CharacterEncoding
用于特殊字符的编码
输出流的一些选项.
可以将多个选项与输出流关联. 第一次使用 OpenWriteOpenAppend 打开流时,可以指定这些选项.
打开一个流,指定使用的默认输出格式应为 OutputForm
将表达式写入流,然后关闭流:
OutputForm 将表达式写入流:
注意,始终可以通过用明确的 Wolfram 系统格式指令(如 OutputFormTeXForm)封装写入到流中的特定表达式来覆盖为特定流指定的输出格式.
选项 PageWidth 给出可用于 Wolfram 系统文本输出的页面宽度. 输出的所有行都已被断开以适应该宽度. 如果不想断开输出行,可以设置 PageWidth->Infinity. 但是,通常你会希望将 PageWidth 设为一个适合于特定输出设备的值. 在许多系统上,必须运行一个外部程序来找出该值. 通过 SetOptions,可对 PageWidth 的默认规则进行设置,如 PageWidth:><<"!devicewidth",以便自动运行外部程序来求出选项的值.
打开一个流,指定页面宽度为 20 个字符:
写入一个表达式,然后关闭流:
表达式的所有行都被断开,每行最多 20 个字符:
选项 CharacterEncoding 允许指定一种字符编码,用来指定通过 WriteWriteString 发送到特定输出流的所有字符串所用的编码. 如果要修改国际字符集或防止出现特定的输出设备接收其无法处理的字符的情况,通常需要使用 CharacterEncoding.
Options[stream]
给出为流设置的选项
SetOptions[stream,opt1->val1,]
重置处于打开状态的流的选项
处置流的选项.
打开一个具有默认设置选项的流:
改变打开的流的 FormatType 选项:
Options 显示为打开的流设置的选项:
再次关闭流:
Options[$Output]
给出通道 $Output 内所有流的选项设置
SetOptions[$Output,opt1->val1,]
设置通道 $Output 内所有流的选项
处理标准输出通道的选项.
在会话的所有时刻,Wolfram 系统都会维护当前打开的所有输入和输出流的列表 Streams[] 及其选项. 在某些情况下,你可能会发现直接查看此列表很有用. 但是,Wolfram 系统不允许你修改列表,除非通过 OpenRead 等间接进行操作.
命名及查找文件

目录操作

文件命名的准确细节因计算机系统而异. 尽管如此,Wolfram 系统提供了一些可以在所有系统上运行的相当通用的机制.
Wolfram 系统假定所有文件都按目录层次结构排列. 如果要查找特定文件,Wolfram 系统必须知道文件名是什么,以及文件所在的目录顺序.
但是,在任何给定时间,都有一个当前的工作目录,可以通过指定文件或其他目录相对于此目录的位置来引用它们. 通常,只需给出名称,毋需提供目录信息就可以引用该目录中实际存在的文件或目录.
Directory[]
当前工作目录
SetDirectory["dir"]
设定当前工作目录
ResetDirectory[]恢复到以前的工作目录
对目录进行操作.
给出了表示当前工作目录的字符串:
将当前的工作目录设置为 Examples 子目录:
现在,你当前的工作目录已改变:
恢复以前的工作目录:
调用 SetDirectory 时,可以给出操作系统可以识别的任何目录名称. 举例来说,在基于 Unix 的系统上,可以使用 .. 符号指定目录层次结构中上一级的目录,用 ~ 指定 "home" 目录.
每次使用 SetDirectory 转到新目录时,Wolfram 语言始终会记住先前的目录. 可以使用 ResetDirectory 返回到先前的目录. 通常,Wolfram 语言会一直保留由 DirectoryStack[] 提供的目录堆栈. 每次调用 SetDirectory 时,都会向堆栈中添加一个新目录,而每次调用 ResetDirectory 时,从堆栈中删除一个目录.
ParentDirectory[]
当前工作目录的父目录
$InitialDirectory
Wolfram 系统启动时的初始目录
$HomeDirectory
家目录,如果有定义的话
$BaseDirectory
Wolfram 系统要加载的整个系统文件的基本目录
$UserBaseDirectory
Wolfram 系统要加载的用户特定文件的基本目录
$InstallationDirectory
Wolfram 系统安装程序所在的顶层目录
特殊目录.

查找文件

每当你需要特定文件时,Wolfram 语言通常都会通过几个步骤来尝试查找所需的文件. 第一步是使用操作系统或外壳程序中存在的任何标准机制.
Wolfram 语言会扫描文件的全名,并查看其中是否包含 *$~?["' 等任何元字符. 如果找到了此类字符,则将全名传递给操作系统或壳进行解释. 这意味着,如果使用的是基于 Unix 的系统,就将 name*$VAR 这样的构建展开. 一般情况下,Wolfram 语言接受操作系统或壳返回的所有内容,并将其视为完整的文件名.
对于输出文件,这是 Wolfram 语言所做操作的结尾. 如果 Wolfram 语言找不到具有指定名称的唯一文件,就会创建该文件.
但是,如果尝试从文件获取输入,那么 Wolfram 语言会进行另一轮处理. 所发生的情况是,Wolfram 语言会查看用于确定与搜索文件相关的目录名称的函数的 Path 选项的值. Path 选项的默认设置是全局变量 $Path.
Get["file",Path->{"dir1","dir2",}]
获取文件,相对于目录 diri 进行搜索
$Path
搜索输入文件所用的相对默认目录列表
搜索文件的路径.
通常,全局变量 $Path 被定义为字符串列表,每个字符串表示一个目录. 每次需要输入文件时,Wolfram 语言实际上是暂时将这些目录依次转换为当前工作目录,然后从该目录中尝试查找你请求的文件.
以下是 $Path 的典型设置. 首先列出当前目录 (.) 和你的家目录 (~):
也可以使用 FindFile 查找文件.
FindFile["name"]
查找将由 Get 和相关函数加载的具有指定名称的文件
FileExistsQ["name"]
确定文件是否存在
查找 $Path 上的文件.
FindFile 搜索 $Path 中的所有目录,并返回将由 GetNeeds 和其他函数加载的文件的绝对名称. FileExistsQ 测试具有给定名称的文件是否存在.
对软件包名称应用 FindFile 将返回该软件包中 init.m 文件的绝对名称.

列出目录的内容

FileNames[]
列出当前工作目录中的所有文件
FileNames["form"]
列出当前工作目录中文件名与字符串模式 form 匹配的所有文件
FileNames[{"form1","form2",}]
列出文件名与任一 formi 匹配的所有文件
FileNames[forms,{"dir1","dir2",}]
给出名称与任一目录 diri 下的 forms 匹配的所有文件的全名
FileNames[forms,dirs,n]
包括子目录中的文件,最多 n 层以下
FileNames[forms,dirs,Infinity]
包括所有子目录中的文件
FileNames[forms,$Path,Infinity]
给出名称与 $Path 中的目录的任何子目录中的 forms 匹配的所有文件
获取特定目录中的文件列表.
FileNames 返回与文件名相对应的字符串列表. 当返回的文件不在当前目录中时,给出相对于当前目录的文件名. 注意,所有名称均以适用于特定计算机系统的格式给出.
这是当前工作目录中以 .m 结尾的所有文件的列表:
下面列出了在当前目录中名称以 a 开头的文件和子目录中名称以 P 开头的文件:
赋给 FileNames 的名称的格式可使用任何 Wolfram 语言字符串模式对象,通常用 ~~ 运算符组合在一起.
给出了当前工作目录中名称与 Test*.m 格式匹配的所有文件的列表:
只列出名称形式为 Test d.m 的文件,其中 d 是一个或多个数字序列:

组成文件名

DirectoryName["file"]
从文件名中提取目录名
FileNameJoin[{"directory","name"}]
从目录名和文件名组合完整的文件名
ParentDirectory["directory"]
给出目录的父目录
FileNameJoin[{"dir1","dir2",,"name"}]
根据目录名称的层次结构组合完整的文件名
FileNameJoin[{"dir1","dir2",}]
根据目录名称的层次结构组合出一个目录名称
对文件名进行操作.
应该意识到,不同的计算机系统可能会以不同的方式给出文件名. 例如,Windows 系统通常以 dir:dirdirname 形式给出名称,而 Unix 系统以 dir/dir/name 形式给出名称. 函数 FileNameJoin 以适合你所使用的特定计算机系统的适当方式组合文件名.
给出了文件名的目录部分:
在与 test.m 相同的目录中构建另一个文件的全名:
FileNameSplit["name"]
将名称拆分为目录和文件名列表
FileNameTake["name",]
提取文件名
FileNameDrop["name",]
去掉文件名的部分内容
FileNameDepth["name"]
获取文件名中路径元素的数量
$PathnameSeparator
操作系统中使用的路径名分隔符
对文件名进行操作.
利用诸如 FileNameSplitFileNameJoin 这样的函数可对文件名进行其他操作. 他们遵循操作系统使用的文件名分隔符,适当地拆分文件名. 默认情况下,FileNameJoin 将使用 $PathnameSeparator 以适合你的操作系统的规范形式生成名称.
如果设置了相关文件的集合,那么在读取一个文件时通常可以很方便地引用另一个文件. 全局变量 $InputFileName 给出当前正在从中获取输入的文件的名称. 然后,通过 DirectoryNameFileNameJoin 可以方便地指定其他相关文件的名称
$InputFileName
当前正在从中获取输入的文件的名称
如何引用 Wolfram 语言当前正在读取的文件.
在 Wolfram 语言中处理文件的一个问题是对于不同的计算机系统,文件和目录名称的形式有所不同. 这意味着在不同系统上,含有标准 Wolfram 语言软件包的文件名可能会完全不同. 通过一系列约定,可以在所有系统上使用相同的命令读取标准 Wolfram 语言软件包. 解决办法就是每个程序包都定义一个所谓的 Wolfram 语言上下文,形式为 name`name`. 在每个系统上,所有文件都根据它们定义的上下文进行命名. 然后,当你使用命令 <<name`name` 时,Wolfram 语言会自动将上下文名称转换为适合你的特定计算机系统的文件名.

标准的文件扩展名

file.m
纯文本格式的 Wolfram 语言表达式文件
file.nb
Wolfram 系统笔记本文件
file.mx
DumpSave 格式的 Wolfram 语言定义
典型的 Wolfram 系统文件的名称.
如果使用的是 Wolfram 系统的笔记本界面,那么 Wolfram 系统的前端将允许你保存完整的笔记本,不仅包括 Wolfram 语言输入和输出,还包括文本、图形和其他内容.
通常 Wolfram 系统的笔记本文件名以 .nb 结尾,大多数 Wolfram 系统版本都执行此约定.
FileBaseName["name"]
文件名,不包括扩展名
FileExtension["name"]
文件名的扩展名
文件名和扩展名.
可通过 FileBaseNameFileExtension 提取文件名及其扩展名.
当你在 Wolfram 系统前端中打开笔记本时,Wolfram 系统将立即显示该笔记本的内容,但是,除非明确要求,通常不会将任何内容发送到内核进行计算.
但是,在 Wolfram 系统笔记本中,可以使用前端的单元菜单将某些单元标识为初始化单元,则每次打开笔记本时,系统都会自动对这些单元的内容进行计算.
单元方括号中的 I 表示第二个单元是一个初始化单元,每次打开笔记本时,系统都会对其进行计算.

16.gif

有时,同时将 Wolfram 资源放在包含说明文字的笔记本中和只含有原始 Wolfram 语言定义的软件包中会为维护带来方便. 可以通过将 Wolfram 语言定义放入笔记本的初始化单元中来完成. 每次保存笔记本时,前端都将允许你保存一个只包含原始 Wolfram 语言定义的关联的 .m 文件.
处理文件和目录
CopyFile["file1","file2"]
将文件 file1 复制为 file2
RenameFile["file1","file2"]
将文件 file1 命名为 file2
DeleteFile["file"]
删除文件
FileByteCount["file"]
给出文件的字节数
FileDate["file"]
给出文件的修改日期
SetFileDate["file"]
将文件的修改日期设为当前日期
FileType["file"]
FileDirectoryNone 给出文件的类型
处理文件的函数.
不同的操作系统具有不同的用于处理文件的指令. Wolfram 语言提供了一组简单的文件操作函数,旨在在所有操作系统下以相同的方式处理文件.
注意,CopyFileRenameFile 将最终文件的修改日期设为与原始文件相同. FileDateDateList 使用的{year,month,day,hour,minute,second} 格式返回修改日期.
CreateDirectory["name"]
创建新目录
DeleteDirectory["name"]
删除空目录
DeleteDirectory["name",DeleteContents->True]
删除目录及其包含的所有文件和目录
RenameDirectory["name1","name2"]
重命名目录
CopyDirectory["name1","name2"]
复制目录及其中的所有文件
处理目录的函数.
读入文本数据
通过 << 可以读取包含以输入形式给出的 Wolfram 语言表达式的文件. 但是,有时你可能需要读取其他格式的数据文件. 例如,可能是由外部程序生成的数据,由一系列用空格分隔的数字组成. 不能按 Wolfram 语言输入直接读取这些数据. 但是,函数 ReadList 可以从文件或输入流中获取此类数据,并将其转换为 Wolfram 语言列表.
ReadList["file",Number]
从文件中读取一系列数字,并将其放入 Wolfram 语言列表中
从文件中读取数字.
下面是由数字组成的文件:
读取文件中的所有数字,返回列表:
ReadList["file",{Number,Number}]
从文件中读取数字,将相邻的一对数字放入单独的列表
ReadList["file",Table[Number,{n}]]
将相邻的 n 个数字放入单独的列表
ReadList["file",Number,RecordLists->True]
将文件的每一行的所有数字放入单独的列表
读入数字块.
将文件中每对相邻的数字放入单独的列表中:
将文件的每一行放入单独的列表
ReadList 以处理以类似 Fortran 的 "E" 表示法给出的数字. 例如,ReadList2.5E+5 读为 . 注意, ReadList可以处理任意精度的数字.
含有以类似 Fortran 的 "E" 表示法给出的数字的文件:
ReadList 可处理这种格式的数字:
ReadList["file",type]
读取特定类型的一系列对象
ReadList["file",type,n]
最多读取 n 个对象
读取各种类型的对象.
ReadList 不仅可以读取数字,还可以读取各种其他类型的对象. 每种类型的对象均由符号(例如 Number)指定.
含有文字的文件:
给出文件中字符的列表,以一个字符的字符串形式给出每个字符:
以下是与文件中每个字节对应的整数代码:
将文件中每一行的数据放入一个单独的列表中:
Byte
数据的一个字节,以整数形式返回
Character
一个字符,以一个字符的字符串形式返回
Real
以类似 Fortran 的表示法给出的近似数
Number
以类似 Fortran 的表示法给出的精确数或近似数
Word由单词分隔符分隔的字符序列
Record
由记录分隔符分隔的字符序列
String
以换行符结束的字符串
Expression
完整的 Wolfram 语言表达式
Hold[Expression]
完整的 Wolfram 语言表达式,在 Hold 内返回
读取的对象的类型.
返回文件 strings 中的单词
ReadList 允许从文件中读取单词. 它认为单词是由单词分隔符分隔的任何字符序列. 可以设置选项 WordSeparators 来指定用作单词分隔符的字符串. 默认值为包含空格和制表符,但不包含标准的标点符号. 请注意,在所有情况下,相邻的单词都可以由任意数量的单词分隔符分隔. ReadList 返回的实际单词中不会包括这些分隔符.
选项名称
默认值
RecordListsFalse
是否将每个记录中的对象单独列出
RecordSeparators{"\r\n", "\n","\r"}
记录分隔符
WordSeparators{" ","t"}
单词分隔符
NullRecordsFalse
是否保留长度为零的记录
NullWordsFalse
是否保留长度为零的单词
TokenWords{}
作为标记的单词
ReadList 的选项.
用字母 e. 作为单词分隔符,将文件 strings 中的文字作为单词序列读入:
Wolfram 语言认为任何数据文件都是由一系列记录组成的. 默认情况下,每一行都被视为一条单独的记录. 通常,你可以设置选项 RecordSeparators 给出一系列记录分隔符. 请注意,单词永远不能越过记录分隔符. 与单词分隔符一样,相邻记录之间可以存在任意数量的记录分隔符,这些分隔符不被视为记录本身的一部分.
默认情况下,文件的每一行都被视为一条记录:
这是一个包含三个句子的文件,每个句子以句号结尾:
将句号和换行符都作为记录分隔符:
将每个句子中的单词放入单独的列表中:
ReadList["file",Record,RecordSeparators->{}]
将整个文件作为一个字符串读入
ReadList["file",Record,RecordSeparators->{{"lsep1",},{"rsep1",}}]
将文件中位于 lsepirsepi 之间的部分放入列表中
RecordSeparators 选项的设置.
含有一些文本的文件:
读取文件 source 中的所有文字,并将其作为一个字符串返回:
给出文件位于 (::) 分隔符之间的部分:
通过选择适当的分隔符,可以选取文件的特定部分:
Wolfram 语言通常允许相邻的记录或单词之间出现任意数量的分隔符. 但是,当出现多个分隔符时,你可能希望假设在每对相邻的分隔符之间出现了空记录空单词. 可以通过设置选项 NullRecords->TrueNullWords->True 来实现.
用冒号分隔的单词的文件:
重复的冒号被视为单个分隔符:
现在,重复的冒号被视为有一个空单词在中间:
大多数情况下,我们都希望用不被视为单词的分隔符来分隔单词. 但是,有时允许用特殊的标记单词(它们本身就是单词)来分隔单词是会带来很多方便. 可以将此类标记单词的列表作为选项 TokenWords 的设置.
下面是一些文本:
读取文本,用指定的标记单词来分隔文本中的单词:
可以使用 ReadList 从文件中读取 Wolfram 语言表达式. 通常,每个表达式都必须以换行符结尾,尽管单个表达式可能会持续多行.
下面的文件含有可用作 Wolfram 语言输入的文本:
exprs 中的文本读入为 Wolfram 语言表达式:
这样可以防止对表达式进行计算:
ReadList 可以将其读取的对象插入任何 Wolfram 语言表达式中. ReadList 的第二个参数可由包含符号(如 NumberWord)的任意表达式组成,这些符号会指定要读取的对象. 例如, ReadList["file",{Number,Number}] 会将其读取的连续数字对插入到列表中. 同样,ReadList["file",Hold[Expression]] 将其读取的表达式放入 Hold 内.
如果 ReadList 在完成读取所需的特定对象之前已到达文件的末尾,则它将插入特殊符号 EndOfFile 来代替尚未读取的对象.
这是一个由数字组成的文件:
到达文件末尾后,符号 EndOfFile 出现,代替尚未读取的数字:
ReadList["!command",type]
先执行指令,然后读取其输出
ReadList[stream,type]
读入任何输入流
从指令和流中读取.
执行 Unix 指令 date,并以字符串形式读取其输出:
OpenRead["file"]打开文件进行读取
OpenRead["!command"]
打开管道进行读取
Read[stream,type]
从流中读取指定类型的对象
Skip[stream,type]
跳过输入流中指定类型的对象
Skip[stream,type,n]
跳过输入流中指定类型的 n 个对象
Close[stream]
关闭输入流
用来从输入流中读取的函数.
ReadList 允许你读取特定文件或输入流中的所有数据. 但是,有时你希望一次只读取一条数据,先测试一下,知道下面将得到什么样的数据.
当你从文件中读取单项数据时,Wolfram 语言将始终记住你在文件中所处的当前指针. 调用 OpenRead 时,Wolfram 语言会设置来自文件的输入流,并将当前指针设为文件的开头. 每次使用 Read 从文件中读取对象时,Wolfram 语言都会将当前指针设为紧接在读取对象之后. 使用 Skip 可以使当前指针跳过一系列对象,不必读取这些对象.
这是一个由数字组成的文件:
打开来自文件的输入流:
从文件中读取第一个数字:
读取第二对数字:
跳过下一个数字:
读取剩余的数字:
关闭输入流:
就像在 ReadList 中一样,可以在 ReadSkip 中使用选项 WordSeparatorsRecordSeparators.
注意,如果你尝试读取文件末尾以后的内容,则 Read 将返回符号 EndOfFile.
搜索文件
FindList["file","text"]
获取文件中包含指定文本的所有行的列表
FindList["file","text",n]
获取包含指定文本的前 n 行的列表
FindList["file",{"text1","text2",}]
获取包含任一 texti 的行
查找含有指定文字的行.
含有一些文本的文件:
返回文件中包含 is 的所有行:
文件中不包含 fourth
默认情况下,FindList 扫描文件中的行,返回含有指定文本的行. 通常,也可以用 FindList 扫描记录,返回包含指定文本的完整记录. 与 ReadList 中一样,选项 RecordSeparators 可以告诉 Wolfram 语言要将哪些字符串视为记录分隔符. 注意,通过将一对列表作为 RecordSeparators 的设置,可以指定不同的左右分隔符. 这样,可以使 FindList 只搜索位于特定分隔符之间的文字.
找出所有含有 And 且以句号结尾的句子
选项名称
默认值
RecordSeparators{"n"}
记录分隔符
AnchoredSearchFalse
是否要求搜索的文字在记录的开头
WordSeparators{" ","t"}
单词分隔符
WordSearchFalse
是否要求搜索的文字作为单词出现
IgnoreCaseFalse
是否将小写和大写字母视为一样
FindList 的选项.
只找出文件中 Here 出现在行的开头的句子:
通常,FindList 会找出出现在记录内任何地方的文字. 但是,通过设置选项 WordSearch->True,可以告诉 FindList 要求查找的文字以单独的单词出现在记录中. 选项 WordSeparators 指定单词分隔符的列表.
文字 th 确实出现在文件中,但不是单词. 因此,FindList 未能得到任何结果:
FindList[{"file1","file2",},"text"]
在任一 filei 中查找文字
在多个文件中搜索.
textfile 两个副本中搜索 third
在由诸如 FileNames 之类的函数生成的文件列表上调用 FindList 通常很有用.
FindList["!command",]
运行外部指令,在其输出中查找文字
在外部程序的输出中查找文本.
在基于文本的界面中运行外部 Unix 指令 date
给出日期中当天的时间:
OpenRead["file"]
打开文件进行读取
OpenRead["!command"]
打开通道进行读取
Find[stream,text]
查找 text 下次出现的地方
Close[stream]
关闭输入流
查找文字下次出现的地方.
FindList 的工作方式是遍历特定文件,查找指定文本出现的地方. 但是,有时你可能需要分批逐次搜索文字出现的地方. 可以使用 Find 执行此操作.
为了使用 Find,首先必须使用 OpenRead 打开输入流. 然后,每次在此流上调用 Find 时,它将搜索指定的文本,并使文件中的当前指针紧跟在找到记录之后. 因此,可以多次调用 Find 查找文字后续出现的地方.
打开 textfile 的输入流:
找到第一个含有 And 的行:
再次调用 Find 给出下一个含有 And 的行:
关闭输入流:
一旦有了输入流,就可以混合调用 FindSkipRead. 如果曾经调用了 FindListReadList,则 Wolfram 语言将直接读取到输入流的末尾.
打开输入流:
找到第一个含有 second 的行,将文件中的当前指针设为下一行的开头:
Read 读取出现在行首的单词:
跳过下面的三个单词:
Wolfram 语言在剩余的文本中查找 is,并输出所有记录:
关闭输入流:
StreamPosition[stream]
找出打开的流中当前指针的位置
SetStreamPosition[stream,n]
设置当前指针的位置
SetStreamPosition[stream,0]
将当前指针的位置设为流的开头
SetStreamPosition[stream,Infinity]
将当前指针的位置设为流的结尾
在流中查找和设置当前指针的位置.
ReadSkipFind 这样的函数通常按顺序在流上操作. 每次调用其中一个函数时,流的当前指针也会随之移动.
有时,你可能需要知道流中当前指针的位置在哪里,并能够对其进行重置. 在大多数计算机系统上,StreamPosition 以整数形式返回当前指针的位置,即距流的开头的字节数.
打开流:
第一次打开文件时,当前指针在开头,StreamPosition 返回 0
读取文件的第一行:
当前指针已经前移:
设置流的当前指针的位置:
现在,Read 返回第一行的剩余部分:
关闭流:
搜索并读取字符串
ReadFind 这样的函数经常被用来处理来自外部文件的文本和数据. 但是,在某些情况下,你可能会发现使用这些函数在 Wolfram 语言中处理字符串也很方便. 可以通过使用函数 StringToStream 来完成,该函数将打开一个输入流,不是从外部文件而是从 Wolfram 语言字符串中读取字符.
StringToStream["string"]
打开输入流,从字符串中读取
Close[stream]
关闭输入流
将字符串视为输入流.
打开一个输入流,从字符串中读取:
从字符串中读取第一个单词
从字符串中读取剩余的单词:
关闭输入流:
与字符串关联的输入流的工作方式和与文件关联的输入流完全相同. 在任何给定时间,流中都会有一个当前位置,当使用如 Read 这样的函数时,该位置会前进. 当前位置由函数 StreamPosition[stream] 以距字符串开头的字符数给出. 可以使用 SetStreamPosition[stream,n] 显式设置当前位置.
与字符串关联的输入流:
当前位置最初是距字符串开头 0 个字符:
从流中读取一个数字:
当前位置距字符串开头 3 个字符:
将当前位置设为距字符串开头 1 个字符:
如果现在从字符串中读取数字,则得到 123 中的 23
将当前位置设为字符串的末尾:
如果现在尝试从流中读取,将始终得到 EndOfFile
关闭流:
特别是在处理大量文本数据时,通常会将相当长的字符串读入 Wolfram 语言,然后使用 StringToStream 以便在 Wolfram 语言中进一步处理这些字符串. 使用 StringToStream 创建输入流后,就可以使用在处理文件时提到的任何函数来读取和搜索字符串.
textfile 的所有内容放入一个字符串中:
为字符串打开输入流:
给出字符串中含有 is 的文本:
将当前位置重置到字符串的开头:
找到字符串中第一次出现 the 的地方,将当前指针置于紧邻其后的位置:
读取紧接在 the 后面的单词
关闭输入流:
二进制文件
ReadWrite 这样的函数处理普通的可打印文本. 但是,在处理外部数据文件或设备时,有时必须到更低层级,直接处理原始的二进制数据. 可以使用 BinaryReadBinaryWrite 来完成.
BinaryRead[stream]
读取一个字节
BinaryRead[stream,type]
读取一个指定类型的对象
BinaryRead[stream,{type1,type2,}]
读取一组对象
BinaryWrite[stream,b]
写入一个字节
BinaryWrite[stream,{b1,b2,}]
写入字节序列
BinaryWrite[stream,"string"]
写入字符串中的字符
BinaryWrite[stream,x,type]
写入指定类型的对象
BinaryWrite[stream,{x1,x2,},type]
写入对象序列
BinaryWrite[stream,{x1,x2,},{type1,type2,}]
写入不同类型的对象
读取和写入二进制数据.
"Byte"
8bit 不带符号的整数
"Character8"
8bit 字符
"Character16"
16bit 字符
"Complex64"
IEEE 单精度复数
"Complex128"
IEEE 双精度复数
"Complex256"
IEEE 四精度复数
"Integer8"
8bit 有符号的整数
"Integer16"
16bit 有符号的整数
"Integer32"
32bit 有符号的整数
"Integer64"
64bit 有符号的整数
"Integer128"
128bit 有符号的整数
"Real32"
IEEE 单精度实数
"Real64"
IEEE 双精度实数
"Real128"
IEEE 四精度实数
"TerminatedString"
以空字符结尾的 8bit 字符的字符串
"UnsignedInteger8"
8bit 不带符号的整数
"UnsignedInteger16"
16bit 不带符号的整数
"UnsignedInteger32"
32bit 不带符号的整数
"UnsignedInteger64"
64bit 不带符号的整数
"UnsignedInteger128"
128bit 不带符号的整数
BinaryReadBinaryWrite 支持的类型.
将字节序列写入文件:
BinaryWrite 自动为文件打开一个流. 将其关闭:
从文件中读取第一个字节,并将其作为整数返回:
从文件中读取第二个 8 位字节,作为字符返回:
读取接下来的 32 位,作为 32bit 整数返回:
ReadWrite 一样,BinaryReadBinaryWrite 也适用于流. 但是,如果给出文件名,它们会自动将指定的文件作为流打开. 要直接创建流,可以使用 OpenReadOpenWrite. 在某些计算机系统上,如果想要将 BinaryReadBinaryWrite 与流一起使用,必须设置选项 BinaryFormat->True,以防止诸如换行符转换之类的问题造成损坏.
使用 Wolfram 语言时,通常不会接触到计算机内部原始形式的数据. 但是,有了 BinaryReadBinaryWrite,事情就不再是这样了. 由此会带来一个小问题,不同的计算机可能会以不同顺序排列组成数字的字节,这由 $ByteOrdering 的设置决定.
将 32bit 的整数写入文件:
关闭文件:
读回整数,但假定相反的字节顺序:
BinaryReadList["file"]
读取文件的所有字节
BinaryReadList["file",type]
读取所有数据,将其视为某种类型的对象
BinaryReadList["file",{type1,type2,}]
将数据视为一系列类型的对象
BinaryReadList["file",types,n]
只读取前 n 个对象
读取完整的二进制文件.
写入 128bit 的实数:
读回数字中的字节:
将字节作为一系列 32bit 的实数读回:
将数据视为包含一个字节和一个 32bit 实数的数据对:
BinaryReadBinaryWrite 在读写原始二进制数据时有很大的灵活性. 但是在许多实际应用中,人们只想处理特定的预定义格式. 可以使用 ImportExport 来执行此操作.
除了许多复杂的格式,ImportExport 还支持包含相同数据元素序列的文件,类型与 BinaryReadBinaryWrite 中的相同. 它们还支持由单个二进制位(用 01 表示)组成的 "Bit" 格式.
生成 C 和 Fortran 表达式
如果你有用 C 或 Fortran 编写的专用程序,可能会需要将用 Wolfram 语言生成的公式插入程序的源代码中. Wolfram 语言可帮助你将数学表达式转换为 C 和 Fortran 表达式.
CForm[expr]
按可以在 C 程序中使用的形式写出 expr
FortranForm[expr]
按可以在 Fortran 中使用的形式写出 expr
Export[file,expr,"C"]
写出计算 expr 的 C 函数
适用于其他编程语言的 Wolfram 语言输出.
这是一个以标准 Wolfram 语言形式编写的表达式:
Fortran 形式的表达式:
下面是以 C 形式给出的同一个表达式. 在 Wolfram 多数版本都提供的 C 标头文件 mdefs.h 中,定义了对象(如 Power)的宏:
如果想要生成 C 形式的表达式,可以通过使用 ExportC 来完成.
这里,整个 C 函数是从 Wolfram 语言的 CompiledFunction 表达式计算得出的:
将 Wolfram 语言表达式转换为 C 或 Fortran 的常见动机之一是试图更快地进行数值计算. 但是 C 和 Fortran 可能比 Wolfram 语言更有效的一个最重要的原因是,在这些语言中,用户总是预先指定每个变量的类型,即整数、实数、数组等.
在 Wolfram 语言中,函数 Compile 执行此类假设,并生成高效的内部代码. 通过将 CompilationTarget 设为 "C",可以使其运行得更快.
Compile[x,expr]
将表达式编译成高效的内部代码
Compile[x,expr,CompilationTarget->"C"]
编译成 C 代码,并链接回 Wolfram 语言
编译 Wolfram 语言表达式.
Wolfram 语言脚本

脚本文件

Wolfram 语言脚本是一个包含 Wolfram 语言指令的文件,用户通常可以在 Wolfram 语言会话中按顺序计算这些指令. 如果需要多次重复这些指令,编写一个脚本会非常有用. 把这些指令收集在一起确保它们按照特定的顺序计算,并且没有忽略任何指令. 如果要运行复杂的、很长的计算,这么做是很重要的.
当你交互式地使用 Wolfram 语言时,可使用 Get 计算包含在脚本文件中的指令. 这个函数也可以通过编程在代码或者其它 .wl 文件中使用.
Get["file"]
读入一个文件,并且运行其中的指令
<<file
Get 的简写形式
从脚本文件读取指令.
对脚本文件的结构没有任何要求. 系统会按顺序读入该文件中给出的任何 Wolfram 语言指令序列并进行计算. 如果你的代码比一个普通指令列表更复杂,可以考虑编写一个更为结构化的程序包,如建立 Wolfram 语言程序包中所述.
当我们不需要用一个交互式的会话时,即你的脚本封装了需要执行的单个计算时,Wolfram 语言脚本会更有用. 例如,计算中涉及繁重的计算任务(如线性代数、优化、数值积分或微分方程的解),并且你不使用排版功能、动态交互或笔记本的时候 .
脚本可以存储在一般的 .wl 程序包文件或专门的 .wls 脚本文件中. 两种文件的内容是一样的:一系列 Wolfram 语言表达式,起始处带有可选的 "shebang" 行,一般用在类似于 Unix 的操作系统(参见 Unix 脚本可执行文件)中. 文件类型中的唯一不同是它们被双击时的行为. 双击程序包文件会在笔记本程序包编辑器中打开文件;双击脚本文件会执行文件,如果操作系统支持的话. 这在 Windows 上特别有用,因为在 Windows 上不可能将程序与特殊文件相关联,只能与文件扩展名关联. 可以在笔记本界面上编辑脚本文件,但是必须使用 文件 打开 来打开.

在本地内核中运行脚本

当从命令行调用 Wolfram 语言内核时,可以使用脚本文件, 对于内核可执行文件,一般使用以下位置.
$ "%ProgramFiles%\Wolfram Research\Mathematica\{First[{}]}\wolfram" -script file.wl
在 Windows 上运行脚本文件.
$ /Applications/Mathematica.app/Contents/MacOS/wolfram -script file.wl
在 macOS 上运行脚本文件.
$ wolfram -script file.wl
在 Linux 上运行脚本文件.
-script 命令行选项指定在特殊的脚本内运行 Wolfram 语言内核,或者以批处理模式运行. 在这种模式下,内核读入指定的文件,并且按顺序计算指令. 通过把输出函数的 PageWidth 选项设为 Infinity,内核关闭默认的换行功能,并且不显示 In[]Out[] 标签. 当在该模式下运行时,标准的输入和输出通道 不会被重定向,数值按 InputForm 进行格式化.
运行带有 -script 选项的 wolfram 等价于用 Get 指令读入文件,唯一的不同之处是:在计算文件中最后一个指令之后,内核停止运行. 这种行为可能会影响 Wolfram Symbolic Transfer Protocol (WSTP) 连接或者通过运行脚本创建的外部进程.

用 WolframScript 运行脚本

还可以使用如下的 WolframScript 解释器运行脚本. -file 标志是可选的.
$ wolframscript -file file.wl
用 WolframScript 运行脚本.
WolframScript 会找到最佳的本地内核运行脚本. 如果没有找到任何本地内核,它会连接至云端并在那里运行脚本. 程序接受各种标志以便控制使用本地内核还是云端内核进行计算. 它还设置脚本参数,允许脚本基于启动的形式或收到的输入来改变行为. 使用 WolframScript 的另一个好处是,输入和输出全部被缓存,允许对其应用各种变换. WolframScript 页面对这些额外选项进行了说明,并提供了范例.
在 Windows 和 Linux 上,WolframScript 一般与 Wolfram 系统一起安装. 在 Mac 上,必须运行与 Wolfram 系统绑定的 "Extras" 安装器才能得到 WolframScript. 默认情况下,这些安装器会把 wolframscript 放在 PATH 中.

Unix 脚本可执行文件

类似于 Unix 的操作系统,以及 Windows 中的 Unix 环境(如 cygwin 和 MinGW),允许编写可执行的脚本文件,可按普通的可执行程序那样运行. 这可以通过在文件开头放上一个解释器行实现. 也可对包含 Wolfram 语言指令的脚本进行同样的操作.
解释器行包括两个字符 #!,它必须是文件中的前两个字符,然后是可执行文件的绝对路径以及其他参数. 为了达到跨平台和机器的最大的兼容性,建议通过如下所示的帮助器 /usr/bin/env 启动 WolframScript. env 程序会找到 PATH 中的 wolframscript 并启动.
#!/usr/bin/env wolframscript

(* generate high-precision samples of a mixed distribution *)
Print /@ RandomVariate[MixtureDistribution[
{1,2},
{NormalDistribution[1,2/10],
NormalDistribution[3,1/10]}],
10, WorkingPrecision -> 50]
脚本文件的例子.
如果要把脚本编译成可执行文件,需要设置可执行权限. 之后,即可通过在一个 shell 提示输入脚本名称来运行脚本.
$ chmod a+x script.wls
$ ./script.wls
使脚本可执行,并且运行它.
解释器行可能另外包含解释器的其他参数. WolframScript 页面上指定了可能的参数.
#!/usr/bin/env wolframscript -linewise -format XML
使用其他参数的解释器行.
Wolfram 语言脚本无需含有 .wl.wls 扩展名. 可执行脚本是与 Unix 操作系统中的任何其他程序等效的功能完整的程序,所以可以在其他脚本、管道中使用,或受控运行等. 每个 Wolfram 语言脚本启动自己的 WolframKernel 拷贝,并且不共享变量或者定义. 注意:同步运行 Wolfram 语言脚本可能受许可证的限制,即可以同时运行多少个内核.
在一个交互式的 Wolfram 语言会话中,可以显式地读入可执行脚本文件并且对其进行计算. 如果第一行以 #! 字符开始,Get 指令通常会忽略脚本的第一行.
可以避免使用 env 程序,但是到 wolframscript 的路径必须是绝对路径. 启动脚本的操作系统机制不使用 PATH 或其他方法找到文件. 而且,到解释器的路径不能包含空格.

Windows 上的脚本

独立的脚本也可以用在 Windows 上. 不像 Unix 类的操作系统,这些脚本必须含有扩展名 .wls 才能被识别为 Wolfram 语言脚本. 可以从 Windows 浏览器中通过双击启动脚本,也可以在命令提示符后键入名称启动. 而 Unix 解释器行,如果出现的话,会被这种启动机制忽略.
> file.wls
从命令提示符启动脚本,等价于双击.
在命令提示符中,可在文件名后传递其他参数. WolframScript 本身看不到这些参数,但是会以参数形式传递给脚本,下一章节会详细描述.
> file.wls arg1 arg2
从命令提示符启动带有两个额外参数的脚本.

脚本参数

当运行一个 Wolfram 语言脚本时,可能常常想要通过在命令行上指定参数来修改脚本的行为. Wolfram 语言代码可以通过 $ScriptCommandLine 访问传递给 Wolfram 语言脚本的参数. 另外,可将标准输入的内容作为变量 $ScriptInputString 中的字符串来处理.
$ScriptCommandLine
启动脚本的命令行
$ScriptInputString
给予脚本的标准输入的内容
变量,给出脚本如何运行的信息.
#!/usr/bin/env wolframscript

(* generate "num" samples of a mixed distribution *)
num = ToExpression[$ScriptCommandLine[[2]]];
Print /@ RandomVariate[
MixtureDistribution[
{1, 2},
{NormalDistribution[1, 0.2],
NormalDistribution[3, 0.1]}
], num, WorkingPrecision -> 50]
脚本范例,file.wls,使用了一个命令行参数.
$ ./file.wls 10
运行脚本,并指定在 Unix 环境下的样本数.
> file.wls 10
运行脚本,并指定 Windows 中的样本数.
访问脚本时,$ScriptCommandLine 是一个列表,其中,脚本名称为第一个元素,其余元素为命令行参数. $ScriptCommandLine 遵循标准的 argv[] 约定. 注意这完全隐藏了到解释器的路径或 #! 行传递的任何参数.
由于类似 Unix 操作系统执行脚本的方式,仅当通过 wolframscript 调用 Wolfram 语言内核时,$ScriptCommandLine 才被设置为非空列表. 如果打算以批处理模式和标准 Unix 脚本模式运行脚本,可通过计算 $ScriptCommandLine==={} 确定当前的执行模式. 然后,应使用 $ScriptCommandLine$CommandLine 来访问命令行参数.