问题描述
我正在设想在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()
我只能读取文件的一部分,因此解决了“读取”部分。但是“写”部分我不知道。我怎样才能有效地仅占用一行,并将文件的其余部分写回去?我希望我不必将该文件的每个字节读入内存,然后再写回磁盘...
我模糊地记得文件系统中的文件只是指向磁盘上某个位置的指针,有什么方法可以将指针简单地移至下一行的开头?
我需要深入了解什么系统调用或什么可以有效地做到这一点,但是我对底层系统知识一无所知。任何帮助表示赞赏!
解决方法
您要的不是标准文件系统可以做到的。在不重写整个文件的情况下,您不能在任何传统OS文件系统中将数据插入文件的开头。这就是他们的工作方式。
那些绝对需要能够执行类似操作而不重写整个文件并仍然使用传统OS文件系统的系统,将在常规文件系统之上构建自己的小型文件系统,以便一个虚拟文件由许多文件组成写入不同文件或文件块的片段。然后,在这样的系统中,您可以在虚拟文件的开头插入数据,而无需重写任何现有数据,方法是将新的数据块写入磁盘,然后将虚拟文件索引(存储在其他文件中)更新为表示您的虚拟文件的第一个块现在来自特定位置。该文件索引指定文件中数据块的顺序以及它们的来源。
大多数需要执行类似操作的程序将改为使用数据库存储记录,然后使用索引和查询来控制顺序,并使基础数据库担心单个位在磁盘上的存储位置。这样,您可以非常有效地在结果查询中的任何位置插入数据。