Prolog:获取与 at_end_of_stream 用于检查文件结尾

Prolog: get vs. at_end_of_stream for checking end of file

我正在使用 prolog 读取文件,想知道以下说法的区别:

processRead(Stream, ...) :- at_end_of_stream(Stream), !.

和:

processRead(Stream, ...) :- get(Stream, Ch), Ch is -1, !.

有没有?

这两种都是非常 low-level 访问文件内容的方法,您应该使用更好的方法。

在SWI-Prolog中,最优雅的解决方案是:

  1. 写一篇描述内容的
  2. 使用 Ulrich Neumerkel 的 library(pio) 及其 phrase_from_file/2 将 DCG 应用于文件。

这有几个优点:您实际上可以交互式地测试 DCG,根本不需要文件。该方法是纯粹的,可以应用于多个方向。等等等等

要事第一!关注 !

如果您需要选择, 总是更喜欢使用 at_end_of_stream/1 而不是 get/2!

  • get/2 弃用 。如果您有 decade-old 遗留代码,请迁移它。

    如果您的代码是新的,请永远不要使用它。绝不。一次都没有。

  • at_end_of_stream/1 标准定义。
  • 几乎 每个现代 Prolog 处理器都支持 at_end_of_stream/1——包括(但不限于) GNU Prolog, SICStus Prolog, SWI Prolog, B-Prolog, and Eclipse CLP.

(晚会迟到) 我强烈建议您永远不要 使用at_end_of_stream/1。相反,我推荐你的第一种方法,即尝试阅读(当然使用标准的东西,比如 get_code/2),然后检查你是否有文件结束指示符。

  1. 据推测,如果流没有结束,无论如何你都会读取一个字符,所以你最好立即读取它并处理(罕见的)EOF 作为你普通处理的一部分字符数。

  2. at_end_of_stream/1 被设计破坏了,因为它是阻塞的(如果从终端读取可能会写一个提示)。因此,对于许多类型的流,在它被另一端关闭之前,实际上不可能确定流是否已经结束,这可能永远不会发生。因此,在 SICStus Prolog 中,at_end_of_stream/1 将失败而不是阻塞,因此使用 at_end_of_stream/1 不会给出您期望的结果。

因此,总是尝试读取是最大限度地便携,很可能更快,并且不会在某些流上做奇怪的事情。