File io 在Common Lisp中逐行读取文件(内存不足)

File io 在Common Lisp中逐行读取文件(内存不足),file-io,closures,common-lisp,generator,state,File Io,Closures,Common Lisp,Generator,State,我正在寻找一种方法,一次读取多个文件1 s-expression(数据列表) 问题是这些文件是巨大的——数百兆字节或千兆字节。我需要内存来计算 对于输出文件 (defun add-to-file (process-result file-path) (with-open-file (os file-path :direction :output :if-exists :append

我正在寻找一种方法,一次读取多个文件1 s-expression(数据列表)

问题是这些文件是巨大的——数百兆字节或千兆字节。我需要内存来计算

对于输出文件

(defun add-to-file (process-result file-path)
  (with-open-file (os file-path :direction :output
                                :if-exists :append
                                :if-does-not-exist :create)
    (print process-result os)))
逐行追加结果字符串或s表达式,这项工作做得很好。(我不知道——也许这不是最有效的方法?)

不久前,我要求提供一个宏,该宏可以使用open file打开任意多个文件,并且可以从主体中访问我可以创建和提供其流变量的所有文件。然而,由于打开的输入文件和输出文件的数量是可变的,我想,对于设计来说,使用这样的调用者调用每个文件——打开它们——找到正确的位置——写入或读取——然后再次关闭它,可能会容易得多

对于输出,给定的函数完成该工作。 但是,对于输入,我希望有一个函数,每次我调用它时,它都会读取下一个lisp表达式(s表达式),并且有一种内存,它在其中读取文件中的最后一次,每次我调用它时,它都会重新打开文件,知道在哪里读取,并返回值,下次读取并返回下一个值,等等。 类似于迭代器上的Python生成器,它生成序列中的下一个值

我希望处理-读入-一个表达式一个表达式地读取文件表达式-以使内存使用最少

你将如何处理这样的任务?或者你有一个好的策略吗?

草图:

创建一个存储上次读取位置的结构或类

(defstruct myfile
  path
  (last-position 0))

(defmethod next-expression ((mf myfile))
  (with-open-file (s (myfile-path mf) :direction :input)
    (file-position s (myfile-last-position mf))
    (prog1
        (read s)
      (setf (myfile-last-position mf) (file-position s))))) 
用法示例:

(defparameter *mf1* (make-myfile :path (pathname "/foo/bar.sexp")))

(print (next-expression *mf1*)) ;; get first s-expr from file
;; do sth else
(myfile-last-position *mf1*)  ;; check current position
;; do sth else
(print (next-expression *mf1*)) ;; gives next s-expr from file

然后编写一个方法来检查新的s表达式是否可用。等等。

打开(和关闭)文件是一项相对昂贵的操作。只需打开需要的文件,处理它们,完成后关闭即可。谢谢@sds-您回答了“使用打开的文件”宏。是的,也许除了用这个宏打开所有文件然后继续。。。我只是想知道是否有一个好的解决方案。一个流已经存储了必要的状态:
(defvar*stream*(open#P)/tmp/input”)
,任何时候需要新数据时,
(read*stream*)
。如果更新文件,则可以读取新内容。@谢谢!非常正确。而且它会更有效。
(defun read或nil(stream)”返回read。如果第二个值为nil,则到达文件结尾。“(处理程序案例(值(读取流)T)(系统::简单文件结尾(c)(值nil nil)))
谢谢@Rainer Joswig!我要试试这个!非常感谢。它工作得很好!非常优雅的解决方案!