首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Scheme R6RS中可以有效地从磁盘加载整个文件吗?

在Scheme R6RS中可以有效地从磁盘加载整个文件吗?
EN

Stack Overflow用户
提问于 2021-05-04 04:59:19
回答 1查看 48关注 0票数 1

以下get_file函数以方案R6RS字符串的形式从磁盘读取文件:

代码语言:javascript
复制
; Gets all characters from a port
(define (read_chars_from_port_rev port result)
  (let ((char (read-char port)))
    (if (eof-object? char)
      result
      (read_chars_from_port_rev port (cons char result)))))

; Gets the contents of a file as a string
; If it doesn't exist, returns empty
(define (get_file file)
  (if (file-exists? file)
    (let ((port (open-input-file file)))
      (let ((text (list->string (reverse (read_chars_from_port_rev port '())))))
        (begin
          (close-input-port port)
          text)))
    ""))

它的工作原理是打开文件,通过尾部调用递归地将char- by -char读取到链表中,直到找到eof,关闭文件,然后反转链表(因为尾部调用)并将其转换为字符串。

比方说,与node.js的readFile相比,这个过程应该很慢,因为它逐个读取字符,并为文件中的每个字符分配一个具有一个单元的链表。理想情况下,我们应该能够将文件作为字符串缓冲区读取,而不需要动态内存分配。

有没有办法使用R6RS中可用的原语来优化get_file

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-04 07:01:19

您可以使用get-string-all

代码语言:javascript
复制
> (let* ((fp (open-input-file "my-file.txt"))
         (buf (get-string-all fp)))
    (close-port fp)
    (display buf))
Four score and seven years ago
our fathers brought forth upon this continent,....

这可以通过使用call-with-input-file变得更加方便。

代码语言:javascript
复制
;;; Returns a string containing the contents of the file `fname`; closes the
;;; input port automatically (unless `get-string-all` does not return for
;;; some reason).
(define (get-file fname)
  (call-with-input-file fname get-string-all))
代码语言:javascript
复制
> (get-file "my-file.txt")
"Four score and seven years ago\nour fathers brought forth upon this continent,....\n"

当所查找的文件不存在时,您可以使用guard来简化返回空字符串的过程(如发布的代码中所示):

代码语言:javascript
复制
(define (guarded-get-file fname)
  (guard (con
          ((i/o-file-does-not-exist-error? con) ""))
    (call-with-input-file fname get-string-all)))
代码语言:javascript
复制
> (guarded-get-file "my-file.txt")
"Four score and seven years ago\nour fathers brought forth upon this continent,....\n"

> (guarded-get-file "oops.txt")
""
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67375744

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档