[英]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-bytes
或in-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-lines
, read-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.