为什么fs.createReadStream ... pipe(res)锁定读取的文件?

水下的

我正在根据这个答案使用express流音频和视频文件相关代码如下:

function streamMedia(filePath, req, res) {
  // code here to determine which bytes to send, compute response headers, etc.

  res.writeHead(status, headers);
  var stream = fs.createReadStream(filePath, { start, end })
    .on('open', function() {
      stream.pipe(res);
    })
    .on('error', function(err) {
      res.end(err);
    })
  ;
}

将字节流传输到客户端上的<audio><video>元素时,这工作得很好但是,在满足这些请求之后,另一个快速请求可以从文件系统中删除正在流式传输的文件。第二个请求失败了。

发生的情况是,只要文件至少被流传输一次(意味着createReadStream在运行上面的代码时调用了a的文件路径),然后出现另一个不同的express请求删除该文件,该文件将保留在文件系统上直到express已停止。一旦Express停止,文件将从文件系统中删除。

这到底是怎么回事?是它fs还是express那个正在锁定文件,为什么?我如何获得释放文件的过程,以便可以将其删除(在读取其内容并将其通过管道传输到响应后,如果有任何未决的内容)?

更新1:

我已经修改了上面的代码autoClose: true以为第二个函数arg设置,并添加了'end''close'事件处理程序,如下所示:

res.writeHead(status, headers);
var streamReadOpts = { start: start, end: end, autoClose: true };
var stream = fs.createReadStream(filePath, streamReadOpts)
    // previous 'open' & 'error' event handlers are still here
    .on('end', function () {
      console.log('stream end');
    })
    .on('close', function () {
      console.log('stream close');
    })

我发现的是,当页面最初使用<video><audio>元素加载时,仅'open'触发偶数。然后,当用户单击播放视频/音频时,发出第二个请求,并且这第二次触发'end''close'事件,随后成功删除文件。

因此,当用户加载具有从调用此函数的请求获取其<video><audio>元素的页面时,文件似乎已被锁定source直到播放该媒体文件后,才发出第二个请求,并且文件已解锁。

我还发现关闭浏览器也会导致'end''close'事件触发,并且文件将被解锁。我的猜测是,我在做快递时出了点问题,res以使其无法正确关闭,但是我仍然不确定那会是什么。

水下的

事实证明,解决方案是在每个请求期间从文件中读取并传送较小的数据块。在我的测试用例中,我正在流式传输一个6MB的MP4视频文件。尽管我可以使用Firefox或chrome重现该问题,但我使用chrome进行了调试,发现客户端阻止了该流

最初加载页面时,会出现一个类似于以下内容的元素:

<video> <!-- or <audio> -->
    <source src="/path/to/express/request" type="video/mpeg" /> <!-- or audio/mpeg -->
</video> <!-- or </audio> -->

正如在OP中引用的其他答案中所记录的那样,chrome将发送带有范围标头的请求,如下所示:

Range:bytes=0-

对于此请求,我的函数正在发送整个文件,我的响应如下所示:

Accept-Ranges:bytes
Connection:keep-alive
Content-Length:6070289
Content-Range:bytes 0-6070288/6070289
Content-Type:video/mp4

但是,chrome并没有读取全部内容它仅读取前3-4MB,然后阻止连接,直到用户操作导致它需要其余文件为止这解释了为什么关闭浏览器或停止express导致文件被解锁的原因,因为它关闭了来自浏览器或服务器端的连接。

我当前的解决方案是一次最多只能发送1MB(旧学校为1MB 1024 * 1024)块。相关的代码可以在OP中引用的问题的其他答案中找到

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

NodeJS:fs.createReadStream有时不读取所需的“开始”和“结束”字节

来自分类Dev

Node.js不关闭由fs.createReadStream()创建的文件

来自分类Dev

侦听 fs.createReadStream 上发出的错误

来自分类Dev

如何在Node.js中使用fs.createReadStream按单词(用空格分隔并返回)(如`/ \ s + / g)读取文件?

来自分类Dev

Gzip不适用于`fs.createReadStream`

来自分类Dev

在try catch块中有多个fs.createReadStream

来自分类Dev

request()和fs.createReadStream()不返回“正确的”值

来自分类Dev

fs.createReadStream 后未执行代码块

来自分类Dev

为什么这个fs循环读取文件名而不读取内容?

来自分类Dev

Firebase Google Cloud Function:createReadStream结果为空文件

来自分类Dev

Node.js createReadStream仅读取大JSON文件的一个数据块

来自分类Dev

如何处理Node.js中的fs.createReadStream()错误?

来自分类Dev

使用fs.createReadStream()和EISDIR同时打开和打开错误

来自分类Dev

http.createServer如何使用fs.createReadStream从needle.post接收数据

来自分类Dev

如何在节点js中将async / await与fs.createReadStream一起使用

来自分类Dev

节点js .10 fs.createReadStream stream2结束事件未触发

来自分类Dev

为什么在尝试读取XML文件时fs.readFile引发意外令牌的语法错误?

来自分类Dev

为什么以下fs.writeFile仅写入最后一个文件中的数据?

来自分类Dev

为什么fs.watch仅在打开要监视的文件时触发?

来自分类Dev

为什么在node.js fs模块中删除文件被命名为“ unlink”?

来自分类Dev

如何使用Node.js createReadStream和createWriteStream写入多个文件

来自分类Dev

createReadStream()引发RangeError:上传文件时超出最大调用堆栈大小

来自分类Dev

Node.js:第一个字符在fs.createReadStream中未定义

来自分类Dev

为什么我的NodeJS脚本在fs.readFile和fs.appendFile处理大量文件的过程中停顿下来。

来自分类Dev

createreadstream是异步的吗?

来自分类Dev

为什么flock不清除锁定文件?

来自分类Dev

如果streamreader不只是为了读取文件而锁定文件,为什么在单击对话框之前将文件锁定?

来自分类Dev

为什么s3fs不能与Apache MINA SSHD像普通文件系统一样工作?

来自分类Dev

用户级别的fs io跳出缓冲区?为什么写文件缓冲区的地址空间应该对齐?

Related 相关文章

  1. 1

    NodeJS:fs.createReadStream有时不读取所需的“开始”和“结束”字节

  2. 2

    Node.js不关闭由fs.createReadStream()创建的文件

  3. 3

    侦听 fs.createReadStream 上发出的错误

  4. 4

    如何在Node.js中使用fs.createReadStream按单词(用空格分隔并返回)(如`/ \ s + / g)读取文件?

  5. 5

    Gzip不适用于`fs.createReadStream`

  6. 6

    在try catch块中有多个fs.createReadStream

  7. 7

    request()和fs.createReadStream()不返回“正确的”值

  8. 8

    fs.createReadStream 后未执行代码块

  9. 9

    为什么这个fs循环读取文件名而不读取内容?

  10. 10

    Firebase Google Cloud Function:createReadStream结果为空文件

  11. 11

    Node.js createReadStream仅读取大JSON文件的一个数据块

  12. 12

    如何处理Node.js中的fs.createReadStream()错误?

  13. 13

    使用fs.createReadStream()和EISDIR同时打开和打开错误

  14. 14

    http.createServer如何使用fs.createReadStream从needle.post接收数据

  15. 15

    如何在节点js中将async / await与fs.createReadStream一起使用

  16. 16

    节点js .10 fs.createReadStream stream2结束事件未触发

  17. 17

    为什么在尝试读取XML文件时fs.readFile引发意外令牌的语法错误?

  18. 18

    为什么以下fs.writeFile仅写入最后一个文件中的数据?

  19. 19

    为什么fs.watch仅在打开要监视的文件时触发?

  20. 20

    为什么在node.js fs模块中删除文件被命名为“ unlink”?

  21. 21

    如何使用Node.js createReadStream和createWriteStream写入多个文件

  22. 22

    createReadStream()引发RangeError:上传文件时超出最大调用堆栈大小

  23. 23

    Node.js:第一个字符在fs.createReadStream中未定义

  24. 24

    为什么我的NodeJS脚本在fs.readFile和fs.appendFile处理大量文件的过程中停顿下来。

  25. 25

    createreadstream是异步的吗?

  26. 26

    为什么flock不清除锁定文件?

  27. 27

    如果streamreader不只是为了读取文件而锁定文件,为什么在单击对话框之前将文件锁定?

  28. 28

    为什么s3fs不能与Apache MINA SSHD像普通文件系统一样工作?

  29. 29

    用户级别的fs io跳出缓冲区?为什么写文件缓冲区的地址空间应该对齐?

热门标签

归档