从文件或流中读取 [英] Read from a file or stream

查看:119
本文介绍了从文件或流中读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

can I work with files as I used to do in Java. Suppose I have a file with 3 lines as follows:

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

现在我怎样才能在程序中使用这三行作为字符串?

Now how can I take use these 3 lines as string in my program??

推荐答案

首先评论:如果你在Prolog中编程,最好是尝试使用像Prolog那样使用文件的文件,而不是就像你以前用Java做的那样。

First a comment: if you program in Prolog, it is probably best to try to work with files like you work with files in Prolog, and not like you used to do this with Java.

并提出建议:阅读文档。它第一次疼,但你会学会喜欢它。 SWI-Prolog在其网站上提供了非常完整且易于搜索的文档。

And a suggestion: Read the documentation. It hurts the first time, but you will learn to like it. SWI-Prolog has a very complete and easy to search documentation available on its web site.

现在:你真的需要更好地了解你实际上是什么尝试使用这些文件。这对于您将用于阅读它们并在程序中表示它们的方法很重要。

Now: you really need to know a bit better what it is that you are actually trying to do with these files. It matters for the approach you will use for reading them, and representing them inside your program.

具体来说:您可以在Prolog中表示文本:

Specifically: you can represent "text" in Prolog as:


  • atoms

  • 字符代码列表

  • 单字符列表原子

  • 如果您使用的是SWI-Prolog 7(作为其中一个标签建议),字符串对象,Prolog的仅SWI扩展

  • atoms
  • list of character codes
  • list of one-character atoms
  • if you are using SWI-Prolog 7 (as one of the tags suggests), string objects, an SWI only extension to Prolog

列表继续,但这些是最开始的。每种方法都有其优势,您使用哪种方法实际上取决于您的应用。

The list goes on, but these are the most obvious ones at the beginning. Every approach has its strengths, and which one you use really depends on your application.

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

This is only the first step, anyway. Depending on what you want to do with the contents of the file, it might be useful to first tokenize it to atoms, or more complex terms.

本答案的其余部分在某种程度上是特定于SWI-Prolog。

The rest of this answer is SWI-Prolog specific, to a certain extent.

如果您正在读取文件,使用纯I / O库和DCG。这种方法有两个问题:你需要了解DCG是什么;如果您尝试从非重新定位流中读取它(例如,它不能与标准输入一起使用),它就不能很好地工作。但是,如果需要实际解析,可以随时读取整个文件并使用DCG。毫无疑问,这是最通用的方法。您可以查看此处,以便有效阅读整个文件。

If you are reading from a file, it might be useful to use Pure I/O library, and DCGs. Two issues with this approach: you need to learn what DCGs are; it does not work nicely if you try to read from a non-repositioning stream (it does not work with standard input, for example). You can always read the whole file, however, and use DCGs, if you need to actually parse. This is the most general approach, without any doubt. You can look here for efficient reading of a whole file.

如果您正在阅读实际的Prolog术语,您可能需要术语读写谓词

If you are reading actual Prolog terms, you might be needing the term reading and writing predicates.

如果你是按行阅读,那么使用 library(readutil)

If you are reading line-wise, it is helpful to use library(readutil).

您可以随时回归使用输入/输出原语,但这非常繁琐且通常是不必要的。

You can always fall back to using input/output primitives, but this is very tedious and usually unnecessary.

一旦你完成阅读,你可以转换为一个char原子的原子或列表,或者字符串。请记住,如果你决定使用字符串,你将会被SWI-Prolog所困扰(至少目前为止),但你将能够使用一些漂亮的谓词直接从流到字符串读取。

Once you are done reading, you can convert to atoms or lists of one-char atoms, or maybe strings. Keep in mind that if you decide to use strings, you will be stuck with SWI-Prolog (at least for the time being), but you'll be able to use some nifty predicates for reading directly from streams to strings.

阅读和写作意味着您需要打开和关闭文件。您还可以使用别名 user_input user_output 等立即访问标准输入和输出流。这些,或者您打开的流/文件是上面链接的许多读写谓词的参数。

Reading and writing means you need to open and close files. You also have immediate access to the standard input and output streams with the aliases user_input, user_output, etc. These, or the streams/files you have opened, are the arguments to many of the reading and writing predicates linked above.

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

Now, a small example: to read a file, and collect each line in a list of character codes, using 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|...], [...|...]|...].

这篇关于从文件或流中读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆