繁体   English   中英

如何将一个巨大的文件加载到Racket中的String或列表中?

[英]How to load a huge file into a String or list in Racket?

我有一个我需要进行操作的巨大文件。 巨大的约 五十万字。

我只想把它读成一个列表或字符串,这样我以后就可以用它做了。

另外我知道我可以使用file-> string或者使用file-> list,file-> lines将它加载到字符串中,但这些似乎需要花费太长时间。

这是将它加载到列表中的正确方法吗?:

(define my-list (with-input-from-file "myFile.txt" read))

每当我运行程序时,我只会打印出第一行。 似乎适用于较小的文件。

我假设有50万个单词,你的意思是你的文件大约是5 GB。

如果是这种情况,你真的不想把整个东西都读到内存中。 我的意思是,当然,整个事情在技术上都适合许多计算机的RAM(虽然肯定不是全部),但它也需要一段时间才能完成。 使用SSD这将需要大约10秒,这是可以的,我猜,根据您的应用程序,它可能100%罚款,但它肯定不是标准桌面应用程序的快速。 但是,如果你是从硬盘读取它,它需要60秒。 这假设您的硬盘驱动器没有碎片化文件,如果是这样,它会更慢。

这两种情况都是理想的最小值,实际上将5 GB文件完全加载到RAM中的速度最慢。 (虽然在一些非常罕见的情况下,这是你想要的,通常在你做高性能计算时。)

正如@Carcigenicate建议的那样,更好的想法是将文件懒惰地传输到你的程序中,这样你就不需要长时间停顿了。 为此,我建议使用in-input-port-bytesin-bytes-lines 这两个都会生成流,然后您可以使用它们来处理数据,第一个流一次为您提供一个字节,另一个为您提供一行字节。 直到你达到EOF。 你可以在for做到这一点

(call-with-input-file "file.txt"
  (lambda (f)
    (for/fold ([counter 0])
              ([i (in-input-port-bytes f)])
      (+ counter 1))

上面的示例是计算文件中字节数的慢速方法。 但它显示了如何使用in-input-port-bytes

还有其他函数可以创建字符流而不是文件in-lines字节: in-linesread-port等。

我有一种强烈的感觉,你的问题不是读取字符串 ,而是将其打印出来

具体来说,读取这个大小的文件似乎需要大约0.03秒。

我使用这个程序生成了一个文件:

#lang racket

(define str
  "Beebe a reeble to one niner big druppy bonker watz. ")

(with-output-to-file "/tmp/foo.txt"
  (λ ()
    (for ([i (in-range (/ 500000 10))])
      (displayln str))))    

然后,我这样读了:

#lang racket

(define a (time (file->string "/tmp/foo.txt")))

...并产生了这个输出:

cpu time: 30 real time: 30 gc time: 17

....表示30毫秒。

请注意,因为我将file->string包装在一个define ,所以我没有将整个内容打印出来。 这需要很长时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM