DefineInputStreamMethod["name",{"fname1"function1,"fname2"function2,… }]
定义一个具有指定名称的自定义输入流方法,使得 Wolfram 语言可以调用流函数 fnamei,用于打开和读取输入流.
DefineInputStreamMethod
DefineInputStreamMethod["name",{"fname1"function1,"fname2"function2,… }]
定义一个具有指定名称的自定义输入流方法,使得 Wolfram 语言可以调用流函数 fnamei,用于打开和读取输入流.
更多信息和选项
- 输入流方法是创建 InputStream 对象的不同方式. DefineInputStreamMethod 允许将新的输入流方法添加到预定义列表中.
- 一个输入流方法可以提供来自新输入源的流,对输入进行过滤(例如应用解密或解压缩),在读入期间执行副作用,或者组合实现这些功能.
- 可以提供下列流函数:
-
"NameTestFunction" 给定名称的流是否能被打开 "ConstructorFunction" 使用此方法打开一个新的输入流 "CloseFunction" 关闭流并且释放它的资源 "ReadFunction" 从流读取字节 "EndOfFileQFunction" 表明流是否没有更多输入可以读取 "WaitForInputFunction" 等待直至有输入可以读取 "SeekFunction" 重新放置输入读取的流中的点 "StreamPositionFunction" 输入读取的流中的当前点 "StreamSizeFunction" 可以从流中读取的字节数目 "SeekableQFunction" 表明流方法是否可以重新放置输入读取的点 "ErrorTextFunction" 指明是否是一个错误 "ClearErrorFunction" 清楚错误提示 "OptionChangesFunction" 修改由 Options[stream] 返回的选项 - 只有 "ConstructorFunction" 必须提供给 DefineInputStreamMethod. 如果函数没有被提供,那么其他函数有一个默认的定义.
- 使用流方法打开的每个 InputStream 都有一个当前状态. 这里流方法可以把诸如句柄的信息存储到内在流资源、当前流为主、最新错误消息和流方法函数需要的其他信息. 初始状态表达式由 "ConstructorFunction" 返回. 其他函数将当前状态视为参数,并且返回新的状态值.
- 如果返回新状态值的函数没有提供,那么默认定义返回未修改的给定状态.
- 如果 Method 选项使用已注册的输入流方法名称,或者当 MethodAutomatic 且该输入流方法的 "NameTestFunction" 对流名称返回 True 时,OpenRead 会使用输入流方法.
- 当 MethodAutomatic 时,OpenRead["name"] 会调用 "NameTestFunction"f 执行 f["name"],并且如果 f 返回 True,则使用输入流方法来构造该流.
- 如果未提供 "NameTestFunction",则默认实现始终返回 False.
- 当 OpenRead 或其他函数打开一个输入流时,它会调用 "ConstructorFunction"f 执行 f[name,caller,opts],其中 name 是流名称(例如文件路径或 URL). caller 是 OpenRead 或其他打开该流的函数,并且可用于发出消息. opts 参数是选项规则. 函数 f 应返回一个列表 {success,state},其中 success 在构造函数成功打开该流时为 True,而 state 是流状态的初始值.
- 当使用 Method{"method","name"value,...} 打开流时,位于 "method" 之后的规则会包含在传递给 "ConstructorFunction" 的 opts 规则中. 这允许将方法特定的设置传递给输入流方法.
- Close[stream] 调用 "CloseFunction"f 执行 f[state]. 这是将在输入流上调用的最后一个函数,因此它应执行所有必要的资源清理.
- 如果未提供 "CloseFunction",默认实现什么也不做.
- 诸如 Read 和 BinaryRead 这样的流读取函数,会在读取之前调用 "WaitForInputFunction"f 执行 f[state],并且应返回新的状态. 如果流方法用于可能间歇性读取输入的情况,例如读取外部进程的输出,则此方法应是等待发生的地方,以便 "ReadFunction" 永远不必等待输入.
- 如果未提供 "WaitForInputFunction",默认函数尽可能快地返回其输入而不等待. 这适用于不需要等待的流方法.
- 流读取函数(例如 Read 和 BinaryRead)会调用 "ReadFunction"f 执行 f[state,n],其中 state 是当前的流状态,而 n 是要返回的最大字节数. 函数 f 应返回一个列表 {{byte1,...},state},其中第一个元素是一个长度不超过 n 的字节值列表,而 state 是新的状态表达式.
- 如果未提供 "ReadFunction",默认实现总是返回空字节列表和不变的状态表达式.
- 如果 "ReadFunction" 返回的字节数少于请求的字节数,则会调用 "EndOfFileQFunction"f 执行 f[state]. 它应当返回一个列表 {eof,state},其中 eof 在输入流已到达其输入源末尾时为 True,否则为 False.
- 默认情况下,"EndOfFileQFunction" 函数返回 {True,state}.
- 如果 "ReadFunction" 返回的字节数少于所请求的字节数,且 "EndOfFileQFunction" 未指示已到达输入末尾,则调用 "ErrorTextFunction"f 执行 f[state]. 函数 f 应返回一个列表 {error,state},其中 error 是错误字符串,而 state 是新状态. 如果没有错误,则 f 应返回 Null,而不是错误字符串.
- 如果未提供 "ErrorTextFunction",默认实现返回 {Null,state}.
- 如果 "ReadFunction" 返回了一个错误字符串,则会调用 "ClearErrorFunction"f 执行 f[state]. 函数 f 应返回一个列表 {Null,state}. 通常,流方法在读取期间可能会将错误文本存储在状态表达式中,因此 "ClearErrorFunction" 应返回一个已清除错误消息的新状态.
- 如果未提供 "ClearErrorFunction",则默认实现返回 {Null,state}.
- StreamPosition 将调用 "StreamPositionFunction"f 执行 f[state]. 函数 f 应返回一个列表 {n,state},其中 n 是打开流中当前位置距开头的字节数. 位置为 -1 表示流位置未知.
- 如果未提供 "StreamPositionFunction",默认实现返回的位置为 -1.
- 打开流时,调用 "StreamSizeFunction"f 执行 f[state]. 函数 f 应返回一个列表 {size, state},其中 size 是输入流的总字节数(如果已知),否则为 -1,而 state 是新的状态表达式(可以不变). 如果流大小已知,可以加快读取速度.
- 如果未提供 "StreamSizeFunction",默认实现将返回大小 -1.
- 打开流时,调用 "SeekableQFunction" f 执行 f[state]. 函数 f 应返回一个列表 {flag,state},其中如果该流方法可以通过 SetStreamPosition 改变其流位置,则 flag 为 True;否则为 False,而 state 是新的状态表达式(也可以保持不变).
- 如果未提供 "SeekableQFunction",默认实现返回 flag 为 False.
- SetStreamPosition 调用 "SeekFunction"f 执行 f[state,pos],其中 pos 是新的流位置. 该位置要么是一个非负整数,表示距流开头的字节数,要么是 Infinity,表示流的末尾. 函数 f 应返回一个列表 {success,state},其中 success 表示流位置是否已成功更改,而 state 表示新的流状态. 仅当流方法的 "SeekableQFunction" 之前已指示支持更改流位置时,才会调用 "SeekFunction".
- 如果未提供 "SeekFunction",则默认实现会返回一个 success 标志,其值为 False.
- "OptionChangesFunction" 用于让流方法更改 Options[stream,Method] 返回的值,适用于选项包含秘密(如密码)的情况.
- Options[stream] 调用 "OptionChangesFunction"f 执行 f[state,opts]. 函数 f 应返回一个列表 {newopts,state},其中 newopts 将被用作 Options 返回的 Method 选项设置.
- 如果已存在同名的输入流方法,DefineInputStreamMethod 将失败.
- 可以使用 RemoveInputStreamMethod 移除输入流方法.
范例
打开所有单元 关闭所有单元基本范例 (1)
DefineInputStreamMethod["StringName", {
"ConstructorFunction" -> ({True, <|"Pos" -> 1, "Text" -> ToCharacterCode[#]|>}&),
"ReadFunction" -> (With[{pos = #["Pos"]},
Replace[Take[#["Text"], {pos, UpTo[pos + #2 - 1]}],
bytes_List :> {bytes, Append[#, "Pos" -> pos + Length[bytes]]}]
]&)
}]strm = OpenRead["Hello, world.
Here is text.", Method -> "StringName"]ReadList[strm, String]ReadList[strm, String]范围 (5)
定义一种使用 "NameTestFunction" 的输入流方法,来打开任何名称以 "text:" 开头的流:
DefineInputStreamMethod["TextName", {
"NameTestFunction" -> StringStartsQ["text:"],
"ConstructorFunction" -> ({True, <|"Pos" -> 1, "Text" -> ToCharacterCode[StringDrop[#, 5]]|>}&),
"ReadFunction" -> (With[{pos = #["Pos"]},
Replace[Take[#["Text"], {pos, UpTo[pos + #2 - 1]}],
bytes_List :> {bytes, Append[#, "Pos" -> pos + Length[bytes]]}]
]&)
}]通过在流名称中包含前缀 "text:",使用 "TextName" 流方法打开一个流:
strm = OpenRead["text:Hello, world.
Here is text."]ReadList[strm, String]Close[strm]DefineInputStreamMethod["FileProgress", {
"ConstructorFunction" -> Function[{name, caller, opts},
Replace[OpenRead[name, BinaryFormat -> True], {
s_InputStream :> {True, <|"Stream" -> s, "End" -> False|>},
_ :> {False, Null}
}]
],
"CloseFunction" -> Function[state, Close[state["Stream"]]],
"ReadFunction" -> Function[{state, n},
Replace[BinaryReadList[state["Stream"], "Byte", n], {
{} :> {{}, Append[state, "End" -> True]},
bytes_List :> (
Print["Read ", Length[bytes], " bytes"];
{bytes, state}
)
}]
],
"EndOfFileQFunction" -> Function[state, {state["End"], state}]
}]使用此输入方法打开一个流,注意它会立即被读取以填充内部缓冲区:
file = FileNameJoin[{$InstallationDirectory, "Documentation/English/System/ExampleData/USConstitution.txt"}];
strm = OpenRead[file, Method -> "FileProgress"]Short[ReadList[strm, String]]Close[strm];未定义搜寻方法的流方法将运作,但是内核需要使用更多内存来支持某些操作. 定义一个流方法,在每次读取时进行打印:
DefineInputStreamMethod["FileProgress", {
"ConstructorFunction" -> Function[{name, caller, opts},
Replace[OpenRead[name, BinaryFormat -> True], {
s_InputStream :> {True, <|"Stream" -> s, "End" -> False|>},
_ :> {False, Null}
}]
],
"CloseFunction" -> Function[state, Close[state["Stream"]]],
"ReadFunction" -> Function[{state, n},
Replace[BinaryReadList[state["Stream"], "Byte", n], {
{} :> {{}, Append[state, "End" -> True]},
bytes_List :> (
Print["Read ", Length[bytes], " bytes"];
{bytes, state}
)
}]
],
"EndOfFileQFunction" -> Function[state, {state["End"], state}]
}]st = OpenRead[FindLibrary["demo"], BinaryFormat -> True, Method -> "FileProgress"];
data = BinaryReadList[st];
Close[st];通过添加对 "SeekableQFunction"、"StreamSize" 和 "SeekFunction" 的支持来重新定义流方法:
RemoveInputStreamMethod["FileProgress"];
DefineInputStreamMethod["FileProgress", {
"ConstructorFunction" -> Function[{name, caller, opts},
Replace[OpenRead[name, BinaryFormat -> True], {
s_InputStream :> {True, <|"Stream" -> s, "Size" -> FileByteCount[name], "End" -> False|>},
_ :> {False, Null}
}]
],
"CloseFunction" -> Function[state, Close[state["Stream"]]],
"ReadFunction" -> Function[{state, n},
Replace[BinaryReadList[state["Stream"], "Byte", n], {
{} :> {{}, Append[state, "End" -> True]},
bytes_List :> (
Print["Read ", Length[bytes], " bytes"];
{bytes, state}
)
}]
],
"EndOfFileQFunction" -> Function[state, {state["End"], state}],
"SeekableQFunction" -> Function[state, {True, state}],
"StreamSizeFunction" -> Function[state, {state["Size"], state}],
"SeekFunction" -> Function[{state, newpos},
SetStreamPosition[state["Stream"], newpos];
{True, state}
]
}]st = OpenRead[FindLibrary["demo"], BinaryFormat -> True, Method -> "FileProgress"];
data = BinaryReadList[st];
Close[st];exampleStreamContents = BinaryReadList[FileNameJoin[{$InstallationDirectory, "Documentation/English/System/ExampleData/USConstitution.txt"}]];
DefineInputStreamMethod["ErrorDemo", {
"ConstructorFunction" -> ({True, <|"Pos" -> 1, "Text" -> exampleStreamContents, "Error" -> Null|>}&),
"ReadFunction" ->
(If[#["Pos"] > 18000,
(* artificially introduce an error *)
{{}, Append[#, "Error" -> "Internal error detected."]},
(* normal reading *)
With[{pos = #["Pos"]},
Replace[Take[#["Text"], {pos, UpTo[pos + #2 - 1]}],
bytes_List :> {bytes, Append[#, "Pos" -> pos + Length[bytes]]}]
]
]&),
"EndOfFileQFunction" -> ({#["Pos"] >= Length[#["Text"]], #}&),
"ErrorTextFunction" -> ({#["Error"], #}&),
"ClearErrorFunction" -> ({Null, Append[#, "Error" -> Null]}&)
}]strm = OpenRead["errordemo", Method -> "ErrorDemo"]Short[ReadList[strm, String]]Read[strm, String]SetStreamPosition[strm, 0]由于 "ClearErrorFunction" 会从状态表达式中移除错误标记,因此该流可以被重新读取:
Read[strm, String]定义一个通过按某个数字“旋转”每个字节来模糊所读文件的输入流方法,但通过使用 "OptionChangesFunction" 隐藏流选项中使用的确切数字:
DefineInputStreamMethod["ObscureFile", {
"ConstructorFunction" -> Function[{name, caller, opts},
Replace[OpenRead[name, BinaryFormat -> True], {
s_InputStream :> {True, <|"Stream" -> s, "End" -> False, "Rotate" -> With[{n = Lookup[opts, "Rotate", 0]}, If[FromCharacterCode[#] === "
", #, Mod[# + n, 256]]&]|>},
_ :> {False, Null}
}]
],
"CloseFunction" -> Function[state, Close[state["Stream"]]],
"OptionChangesFunction" -> Function[{state, options}, {FilterRules[options, Except["Rotate"]], state}],
"ReadFunction" -> Function[{state, n},
Replace[BinaryReadList[state["Stream"], "Byte", n], {
bytes_List :> {Map[state["Rotate"], bytes], Append[state, "End" -> bytes === {}]}
}]
],
"EndOfFileQFunction" -> Function[state, {state["End"], state}]
}]file = FileNameJoin[{$InstallationDirectory, "Documentation/English/System/ExampleData/USConstitution.txt"}];
strm = OpenRead[file, Method -> {"ObscureFile", "Rotate" -> 7}]Read[strm, String]当检查流选项时,参数 "Rotate" 已通过 "OptionChangesFunction" 被隐藏:
Options[strm]Close[strm];技术笔记
-
▪
- 流式方法
文本
Wolfram Research (2012),DefineInputStreamMethod,Wolfram 语言函数,https://reference.wolfram.com/language/ref/DefineInputStreamMethod.html.
CMS
Wolfram 语言. 2012. "DefineInputStreamMethod." Wolfram 语言与系统参考资料中心. Wolfram Research. https://reference.wolfram.com/language/ref/DefineInputStreamMethod.html.
APA
Wolfram 语言. (2012). DefineInputStreamMethod. Wolfram 语言与系统参考资料中心. 追溯自 https://reference.wolfram.com/language/ref/DefineInputStreamMethod.html 年
BibTeX
@misc{reference.wolfram_2026_defineinputstreammethod, author="Wolfram Research", title="{DefineInputStreamMethod}", year="2012", howpublished="\url{https://reference.wolfram.com/language/ref/DefineInputStreamMethod.html}", note=[Accessed: 09-September-2026]}
BibLaTeX
@online{reference.wolfram_2026_defineinputstreammethod, organization={Wolfram Research}, title={DefineInputStreamMethod}, year={2012}, url={https://reference.wolfram.com/language/ref/DefineInputStreamMethod.html}, note=[Accessed: 09-September-2026]}