我正在使用 Express 传输音频和视频文件根据这个答案 https://stackoverflow.com/a/24977085/304832。相关代码如下:
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>
and <video>
客户端上的元素。然而,在满足这些请求之后,另一个快速请求可以删除从文件系统流式传输的文件。第二个请求有点失败。
发生的情况是,只要文件至少被流式传输一次(意味着createReadStream
在运行上面的代码时为文件路径调用),然后另一个不同的 Express 请求进入以删除该文件,该文件保留在文件系统上,直到 Express 停止。一旦express停止,这些文件就会从文件系统中删除。
这里究竟发生了什么?是吗fs
or express
那是锁定文件,为什么,以及如何让进程释放该文件以便可以删除它(在读取其内容并通过管道传送到响应之后,如果有待处理的内容)?
更新1:
我修改了上面的代码来设置autoClose: true
对于第二个函数 arg,并添加了两个'end'
and '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>
or <audio>
元素,仅'open'
甚至被解雇。然后,当用户单击播放视频/音频时,会发出第二次请求,这第二次,两个请求'end'
and 'close'
事件触发,随后删除文件成功。
因此,当用户加载具有以下内容的页面时,该文件似乎被锁定<video>
or <audio>
获得它的元素source
来自调用此函数的请求。直到播放该媒体文件后才会发出第二个请求,并且文件会被解锁。
我还发现关闭浏览器也会导致'end'
and 'close'
要触发的事件以及要解锁的文件。我猜我的快递做错了res
使其无法正确关闭,但我仍然不确定那可能是什么。