【问题标题】:Read from a file or stream从文件或流中读取
【发布时间】:2014-09-23 21:57:05
【问题描述】:

我可以像以前在 Java 中那样处理文件吗?假设我有一个包含 3 行的文件,如下所示:

 This is hello world.
 This is not hello world.
 This is a story of a young boy.

现在如何在我的程序中使用这 3 行作为字符串??

【问题讨论】:

标签: io prolog


【解决方案1】:

首先评论:如果您在 Prolog 中编程,最好尝试像在 Prolog 中处理文件一样处理文件,而不是像以前使用 Java 那样处理文件。

还有一个建议:阅读文档。第一次很痛,但你会学会喜欢它。 SWI-Prolog 在其网站上有一个非常完整且易于搜索的文档。

现在:您确实需要更好地了解您实际尝试对这些文件执行的操作。这对于您阅读它们并在程序中表示它们的方法很重要。

具体来说:您可以在 Prolog 中将“文本”表示为:

  • 原子
  • 字符代码列表
  • 单字符原子列表
  • 如果您使用的是 SWI-Prolog 7(如其中一个标签所示),字符串对象,Prolog 的仅 SWI 扩展

列表还在继续,但这些是最明显的开头。每种方法都有其优势,而您使用哪种方法实际上取决于您的应用程序。

无论如何,这只是第一步。根据您要对文件内容执行的操作,首先将其标记为原子或更复杂的术语可能会很有用。

这个答案的其余部分在一定程度上是特定于 SWI-Prolog 的。

如果您正在读取文件,使用Pure I/O library 和 DCG 可能会很有用。这种方法有两个问题:您需要了解 DCG 是什么;如果您尝试从非重新定位流中读取,它就不能很好地工作(例如,它不适用于标准输入)。但是,如果您需要实际解析,您始终可以读取整个文件并使用 DCG。这是最通用的方法,毫无疑问。您可以查看here 以高效读取整个文件。

如果您正在阅读实际的 Prolog 术语,您可能需要term reading and writing predicates

如果您是逐行阅读,使用library(readutil) 会很有帮助。

您总是可以退回到使用input/output primitives,但这非常乏味且通常没有必要。

阅读完毕后,您可以convert to atoms or lists of one-char atoms,或者strings。请记住,如果您决定使用字符串,您将被 SWI-Prolog 卡住(至少暂时如此),但您可以使用一些漂亮的谓词直接从流读取到字符串。

读写意味着你需要open and close files。您还可以使用别名user_inputuser_output 等立即访问标准输入和输出流。这些或您打开的流/文件是上面链接的许多读写谓词的参数。

现在,一个小例子:读取文件,并收集字符代码列表中的每一行,使用library(readutil)

file_to_lines(Filename, Lines) :-
    setup_call_cleanup(
        open(Filename, read, In),
        stream_to_lines(In, Lines),
        close(In)
    ).

stream_to_lines(In, Lines) :-
    read_line_to_codes(In, Codes),
    stream_to_lines_rest(Codes, In, Lines).

stream_to_lines_rest(end_of_file, _In, []) :- !.
stream_to_lines_rest(This, In, [This|Rest]) :-
    read_line_to_codes(In, Next),
    stream_to_lines_rest(Next, In, Rest).

如果您将其保存在名为 rf.pl 的文件中:

?- [rf].
true.

?- file_to_lines('rf.pl', Lines), forall(member(L, Lines), format("~s~n", [L])).
file_to_lines(Filename, Lines) :-
    setup_call_cleanup(
        open(Filename, read, In),
        stream_to_lines(In, Lines),
        close(In)
    ).

stream_to_lines(In, Lines) :-
    read_line_to_codes(In, Codes),
    stream_to_lines_rest(Codes, In, Lines).

stream_to_lines_rest(end_of_file, _In, []) :- !.
stream_to_lines_rest(This, In, [This|Rest]) :-
    read_line_to_codes(In, Next),
    stream_to_lines_rest(Next, In, Rest).

Lines = [[102, 105, 108, 101, 95, 116, 111, 95|...], [32, 32, 32, 32, 115, 101, 116|...], [32, 32, 32, 32, 32, 32|...], [32, 32, 32, 32, 32|...], [32, 32, 32, 32|...], [32, 32, 32|...], [], [115|...], [...|...]|...].

【讨论】:

    猜你喜欢
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多