【发布时间】:2020-12-23 10:20:39
【问题描述】:
我设想在 node.js 中实现一个可以像操作堆栈数据结构一样操作磁盘上的文件的实现。
假设文件是 utf-8 编码的纯文本,堆栈的每个元素对应文件中的 '\n' 分隔行,堆栈顶部指向该文件的第一行。我想要可以同时读写文件的东西。
const file = new FileAsStack("/path/to/file");
// read the first line from the file,
// also remove that line from the file.
let line = await file.pop();
为了天真地实现这样的接口,我可以简单地将整个文件读入内存,当.pop()从内存中读取时,将剩余部分写回磁盘。显然这种方法并不理想。想象一下处理一个 10GB 的文件,这将是内存密集型和 I/O 密集型的。
使用fs.read() 我只能读取文件的一部分,因此“读取”部分已解决。但是“写”部分我不知道。我怎样才能有效地只取一行,然后将文件的其余部分写回它?我希望我不必将该文件的每个字节都读入内存然后写回磁盘...
我模糊记得文件系统中的文件只是指向磁盘上某个位置的指针,有什么方法可以简单地将指针移到下一行的开头?
我需要了解什么系统调用或任何可以有效做到这一点,但我对低级系统的东西很无知。任何帮助表示赞赏!
【问题讨论】:
-
您所要求的不是标准文件系统可以做到的。在我看来,这听起来更像是您想使用一个数据库,该数据库可以以任何有效的方式存储数据,然后按照查询和索引指定的特定顺序将其返回给您。这样,您可以将数据添加到查询的开头,而无需重写整个数据文件。
-
哦……听到这个消息我很难过。感谢您的建议,但我确实需要在这个特定的任务中处理原生 fs。
-
好吧,在任何传统的 OS 文件系统中,您都无法在不重写整个文件的情况下将数据插入到文件的开头。这就是他们的工作方式。您可以在 OS 文件系统之上构建自己的文件系统,在其中将数据分成多个文件,然后有一些主索引文件告诉您各种数据的顺序应该是什么(有点像虚拟文件)。这样,您可以在开头插入数据而无需重写除主索引之外的任何数据。但是,这可能会变得非常复杂,非常快。
-
也许如果您告诉我们更多关于这里要解决的实际问题及其要求(而不是您尝试解决它),我们可以就最适合使用的技术提出更好的建议解决这类问题。
-
@jfriend00 我问这个更多是出于好奇而不是出于实际原因。当我预处理一些巨大的数据集并想要检查处理过的部分时,我突然想到了一个想法。如果不可能,我可以将偏移量存储到文件中而不写入它。
标签: node.js filesystems system-calls