Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
File io EMACS Lisp程序员如何为非编辑目的读取文本文件?_File Io_Emacs_Elisp - Fatal编程技术网

File io EMACS Lisp程序员如何为非编辑目的读取文本文件?

File io EMACS Lisp程序员如何为非编辑目的读取文本文件?,file-io,emacs,elisp,File Io,Emacs,Elisp,当EMACS Lisp程序员想要编写大致相当于 for line in open("foo.txt", "r", encoding="utf-8").readlines(): ...(split on ws and call a fn, or whatever)... 当我查看EMACS lisp帮助时,我看到了关于将文件打开到文本编辑缓冲区的函数——这与我的意图不完全相同。我想我可以编写函数来访问文件的行,但是如果我这样做了,我不希望用户看到它,而且,从文本处理的角度来看,它似乎不

当EMACS Lisp程序员想要编写大致相当于

for line in open("foo.txt", "r", encoding="utf-8").readlines():
    ...(split on ws and call a fn, or whatever)...

当我查看EMACS lisp帮助时,我看到了关于将文件打开到文本编辑缓冲区的函数——这与我的意图不完全相同。我想我可以编写函数来访问文件的行,但是如果我这样做了,我不希望用户看到它,而且,从文本处理的角度来看,它似乎不是很有效

  • 是的,就是您想要做的:访问缓冲区中的文件,并对该缓冲区中的文本进行操作

  • 您不必显示缓冲区,即用户不必看到它

  • 至于效率:在缓冲区中操纵文本通常是操纵文本最有效的方法


  • 您可以通过多种方式访问缓冲区中的文件。您可能希望为此使用现有的文件缓冲区,具体取决于用例。也就是说,如果文件已经在Emacs中“打开”,那么您可能需要使用其缓冲区

    或者,您可能希望忽略已“打开”文件的任何现有文件缓冲区,并将该文件重新读取到新的缓冲区中。为此,@Sean提到,您可以使用
    insert file contents
    和您创建的缓冲区。您可以使用
    with temp buffer
    generate new buffer
    创建缓冲区,这同样取决于您想要/需要对其执行的操作

    如果您确实希望重用已经访问文件的缓冲区,您可以测试它是否在内存中被修改,它是否被缩小,等等,并执行适合您的用例的任何操作。您可以使用函数
    查找缓冲区访问
    检查是否已经有缓冲区访问文件(使用任何路径/文件名)

    要访问该文件,利用正在访问它的任何现有缓冲区,您可以使用
    find file noselect
    。该函数返回访问文件的缓冲区,因此您可以使用当前缓冲区将该缓冲区作为第一个参数传递给
    。下面是一个简单的例子

    (使用当前缓冲区(let((启用局部变量())(查找文件noselect文件))
    用缓冲区中的文本做一些事情。
    ;可选地将缓冲区保存回文件。
    )
    

    (将
    enable local variables
    绑定到
    nil
    是一个很小的优化,在通常情况下,您不需要处理缓冲区局部变量。)

    我认为原始Python代码的更直接翻译如下:

    (with-temp-buffer
      (insert-file-contents "foo.txt")
      (while (search-forward-regexp "\\(.*\\)\n?" nil t)
        ; do something with this line in (match-string 1)
        ))
    
    我认为使用临时缓冲区的
    /
    插入文件内容
    通常比使用当前缓冲区的
    /
    查找文件noselect
    更可取,因为前者保证您使用的是整个文件内容的新副本。对于后一种构造,如果您碰巧已经有一个缓冲区访问目标文件,那么该缓冲区将由
    find file noselect
    返回,因此如果该缓冲区已缩小,则在处理该文件时,您只能看到该文件的该部分

    请记住,逐行处理文件可能更方便。例如,这是一个表达式,返回文件中所有连续数字序列的列表:

    (with-temp-buffer
      (insert-file-contents "foo.txt")
      (loop while (search-forward-regexp "[0-9]+" nil t)
            collect (match-string 0)))
    

    (require'cl)
    首先引入
    循环
    宏。

    如果逐行处理文件,使用
    转发行
    行尾
    通常更快。根据我的经验,如果最后一行可能以新行结尾,则使用
    转发行
    和kin来识别文件的结尾有点棘手。
    查找文件noselect
    的问题是如果用户已经访问了文件这就是为什么最好在临时缓冲区中使用
    insert file
    ,就像肖恩的回答一样。@jch:不,泛化的“它更好”是错误的。这完全取决于你想要/需要做什么-解决方案/实现的魔鬼在于问题/需求的细节。这个问题的重要答案是我前面提到的,如1,2,3。所提出的问题是基于一个误解,1,2,3应该澄清。