gpt4 book ai didi

javascript - 如何异步写入和读取 Node 中的同一文件?

转载 作者:搜寻专家 更新时间:2023-10-31 23:51:47 25 4
gpt4 key购买 nike

我有通过 websocket 传入的数据。它以 20 毫秒的 block 发送二进制数据。我需要连接这些 block 中的每一个,以便后端进程可以在数据传入时将其作为连续流读取。

//Create the file and append binary as it comes in

tmp.file({postfix: '.raw' },function (err, path, fd, cleanup) {
if (err) throw err;
newPath = path
fs.appendFile(newPath, new Buffer(binary), (err) => {
if (err) throw err;

})
})

//Read the file as it is written
fs.createReadStream(newPath).pipe(recStream);

现在我只是在 createReadStream 上有一个简单的半秒延迟,以确保文件中有数据。

这当然让人感觉不对,而且不起作用。解决这个问题的正确方法是什么?

最佳答案

在这种情况下,最好的办法是告诉您从中接收数据的服务器暂停,直到您准备好处理更多数据 (drain)。假设这不是您的选择:

首先将传入数据写入目标流。如果 write(chunk) 返回 false,这意味着流的内部缓冲区已满;是时候开始将后续数据缓冲到磁盘了。 (您刚刚写入的 chunk 导致 false 返回值缓冲;不要将其写入磁盘 -- false 并不意味着写入失败,它只是一个信号,表明缓冲区的数据多于 highWaterMark 。)

在一个临时文件夹中,创建一个新文件 (A) 写入流并将传入数据的下一个 block 写入其中。这样做直到您的目标流发出 drain 事件。

当您的目的地排水时:

  1. 换出缓冲文件。关闭当前缓冲区文件 A 并创建一个新的临时文件 B 以开始向其中写入新的传入数据。
  2. 在临时文件 A 上打开一个读取流,并开始将数据从它传输到目标流中。您可能无法使用实际的 pipe() 方法,因为它会在您到达临时文件末尾时发出数据结束信号,这不是我们想要的,因为它不是实际的所有传入数据结束。 ( Look at what pipe() does 并自己实现,减去调用 end()。)
  3. 当临时文件的流 A 发出 end 时,删除文件 A。然后返回到步骤 1 并使用文件 B 再次开始该过程。 (如果在此期间没有数据写入文件 B,则返回无缓冲操作,将传入数据直接写入目标流。)

一旦服务器发出信号表明它已完成发送数据并且所有数据都已从您的临时文件中读出,write(null) 到目标流中以发出信号没有更多的数据。全部完成!

通过在临时缓冲区文件之间进行交换并在处理完数据后将其删除,您不必担心在将数据写入文件时读取数据。另外,您不必在磁盘上缓冲整个传入数据流。

当然,这确实假设您的存储介质保证接受写入的速度比您通过网络接收数据的速度快。这可能是安全的,但如果这个假设不正确,事情可能会崩溃。 使用生产系统对此进行测试 - 传入数据的峰值速率是多少,您可以多快写入生产系统上的磁盘?

关于javascript - 如何异步写入和读取 Node 中的同一文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42655269/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com