给定以下代码:
async function (req, res, next) {
const fd = await fs.open("myfile.txt")
fs.createReadStream(null, { fd, autoClose: false })
.on('error', next)
.on('end', () => fs.close(fd))
.pipe(res)
}
如果客户端在下载整个文件之前断开连接会怎样?即 end
是否仍会被调用,或者文件描述符是否已泄漏,如果是,我该如何修复?如果调用“end”是否意味着即使客户端不再监听它也会读取整个文件?
请注意,我知道我可以在没有 fd
的情况下执行此操作,但这是对更复杂代码的简化。
最佳答案
看起来文件不会关闭,或者至少不会调用您的 end
事件处理程序。
您可以为此创建测试,但这是我的:
const http = require('http');
const fs = require('fs');
var server = http.createServer(function (req, res) {
console.log('server request received');
const fd = fs.openSync('myfile.txt', 'r');
fs.createReadStream(null, { fd, autoClose: false })
.on('error', err => {
console.error('file error', err);
})
.on('end', () => {
console.log('file end');
fs.close(fd);
})
.on('close', () => {
console.log('file closed');
})
.pipe(res)
.on('error', err => console.error('server stream error', err))
.on('end', () => console.log('server stream end'))
.on('close', () => console.log('server stream closed'))
;
});
server.listen(0, 'localhost', () => {
const address = server.address();
var req = http.request({port: address.port}, function (res) {
res.on('data', data => {
console.log('response data');
// Comment next line to read whole file.
req.abort();
});
res.on('end', () => {
console.log('response ended');
setTimeout(() => server.close(), 1000);
});
req.once('abort', () => {
console.log('request aborted');
});
});
req.end(() => {
console.log('request sent');
});
});
为了简化运行测试,我删除了 async/wait。
当 req.abort()
被调用时,我得到以下输出:
request sent
server request received
response data
request aborted
response ended
server stream closed
注释该行并允许代码读取整个文件后:
request sent
server request received
response data
response data
response data
response data
response data
response data
file end
response data
response ended
为了创建测试 myfile.txt
我使用了以下命令:
dd if=/dev/zero of=myfile.txt bs=1k count=200
关于javascript - 文件下载和客户端断开连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37508826/