Progressively building a large text chunk and then writing it to a file
我是 Common Lisp 的新手,正在尝试构思生成大型文本文件的最佳方法。我基本上看到两个选项:
创建一个字符串并不断添加,然后将此字符串写入
文件输出流只有一次,仅在我的迭代最后结束时
创建一个文件流并在程序构建文本文件时一遍又一遍地不断写入
也许与 1 类似的是:
3. 创建一个字符串输出流并写入它,然后将此流写入一个新的文件流。
问题1
- 2 似乎效率低下?这不是通常的日志记录方式吗?
-
但是,如果您执行 1,并且您对内容有多大有所了解,则可以从一开始就使字符串足够大(实际上,您可以将其与 3 结合使用;您可以创建一个字符串输出流写入一个特定的字符串),然后在最后写出来。
-
它是关于读取文件,而不是写入文件,但您可能对一篇关于将文件内容读入字符串的文章感兴趣,在 Common Lisp 中 Slurping 文件。一些基于块的 IO 可能会在这里提供一些见解。例如,如果你创建了一个大字符串,你可以用 write-sequence 写它。那篇文章发现 read-sequence 是读取文件内容的最快方法;也许 write-sequence 会适合写作。
-
@JoshuaTaylor 如果字符串确实可以处理非常大的尺寸,也许我的担忧不是什么大问题。字符串或字符串输出流的大小是否有实际限制?对于一个文件,你不会想到这个问题,但是如果我要生成许多文件,并且每个文件都需要用该文件中的每一行文本打开和关闭(因为文本生成算法),如果字符串可以处理大尺寸,我认为只从一个非常大的字符串写入一次所有文件是更明智的。
-
不过,您不需要打开和关闭文件,对吗?您不能打开文件并保持打开状态直到您完成它吗?
-
@JoshuaTaylor 好吧,你让我在那里。我可以组织一些可能的事情。我正在生成相关文件的集合,有时在移动到其他部分之前同时写入每个文件的相同部分很方便,因此经常打开和关闭。
-
如果不出意外,您可以拥有一个将路径名映射到流的哈希表。只需根据需要拉起流,写一些东西,然后继续下一个任务。之后一定要关闭它们。 :)
-
快速的 (time (with-open-file (s"test.txt" :direction :output :if-does-not-exist :create :if-exists :append) (format s"Test string"))) 平均给我 270-300 微秒。 IMO,在尝试优化可能不是问题的东西之前,您应该先进行测量。先打开再关闭。如果这太慢,请保持流打开。
打开文件流并在所有工作中保持打开状态,然后关闭它并在必要时移至另一个流。无需不断重新打开和关闭文件。