我有一个大的csv文件与用户数据。我有一个端点,它获取一个用户,并应该返回一个布尔值,指示该用户是否存在于文件中。为了避免内存不足,我以流的形式读取文件,并使用getLines
,这是一种懒惰的方式。下面是我的代码:
def readUsers(filePath: Path): IO[Seq[User]] = {
Stream
.eval(IO(scala.io.Source.fromFile(filePath.toFile)))
.flatMap(source => Stream.fromIterator[IO](source.getLines(), 64))
.map(line => line.split(",")
.map(cols => User(cols(0), cols(1), cols(2), cols(3)))
.compile
.toList
}
def isUserExists(user: User, users: IO[Seq[User]]): IO[Boolean] =
users.map(_.contains(user))
字符串
当应用程序启动时,我为users
分配一个值:
val users = readUsers(filePath)
型
并在调用端点时将其发送到isUserExists
函数。
我的问题是:
toList
是否将整个文件保存在内存中?
1.如果是,如何避免?我应该删除toList
并迭代isUserExists
中的每一行吗?
1.当文件的内容发生变化时,由于users
是一个IO值,它是否会反映在端点中?
2条答案
按热度按时间iswrvxsc1#
字符串
fs2.io
将正确管理资源lg40wkob2#
是的,你的问题是你把流变成了一个具体而完整的列表。为了从流中受益,你必须尽可能多地使用流函数和引用。我建议
readUsers
返回一个fs2.Stream[IO, User]
,然后开始将Streams作为一个“主要”类型,在整个应用程序的签名中使用。随着您对Streams越来越熟悉,使用起来应该会更自然。字符串
就示例而言,这并没有真正展示fs流的强大功能,因为exists()有效地立即耗尽了整个流。我不确定代码是如何使用的,但是您希望只遍历一次流,因此重复isUserExist调用不一定适合最佳用例。